Skip to content

Commit

Permalink
wip(server): 添加管理员管理、认证、登录等
Browse files Browse the repository at this point in the history
  • Loading branch information
wsvaio committed Jan 12, 2024
1 parent 38b19ec commit a7e9b73
Show file tree
Hide file tree
Showing 26 changed files with 394 additions and 272 deletions.
52 changes: 29 additions & 23 deletions components/background/index.vue
Original file line number Diff line number Diff line change
@@ -1,33 +1,39 @@
<script setup lang="ts">
const { data, execute } = await useFetch<Record<any, any>>("/api/common/image", {
query: computed(() =>
useMainStore().easterEgg
? {
type: "dongman",
}
: undefined
),
query: computed(() =>
useMainStore().easterEgg
? {
type: "dongman",
}
: undefined
),
});
useIntervalFn(() => {
execute();
execute();
}, 18000);
</script>

<template>
<div
pos="fixed left-0 top-0"
w="full"
h="100dvh"
:style="{
background: `url(${data?.content}) center / cover fixed`,
transition: 'all 16s steps(16) 1s',
}"
/>
<client-only>
<img
:src="data?.content" pos="absolute" w="0" h="0"
left="-100px" @load="useMainStore().globalLoading = false"
/>
</client-only>
<div
pos="fixed left-0 top-0"
w="full"
h="100dvh"
:style="{
background: `url(${data?.content}) center / cover fixed`,
transition: 'all 16s steps(16) 1s',
}"
/>
<client-only>
<img
:src="data?.content"
pos="absolute"
w="0"
h="0"
left="-100px"
@load="useMainStore().globalLoading = false"
@error="useMainStore().globalLoading = false"
/>
</client-only>
</template>
64 changes: 64 additions & 0 deletions composables/useLoadMore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { type DataType, type LoadMoreBaseOptions, useLoadMore } from "vue-request";

export default <T extends { total: number; list: any[]; page: number }>(
service: (page: number) => Promise<T>,
options?: LoadMoreBaseOptions<DataType>
) => {
const {
dataList,
noMore,
loadingMore,
data,
refreshAsync: _refreshAsync,
loading,
loadMoreAsync: _loadMoreAsync,
} = useLoadMore(
async data => {
const result = await service((data?.page || 0) + 1);
return {
list: result.list,
total: result.total,
page: result.page,
};
},
{
isNoMore: data => !!data && data?.list?.length >= data.total,

...options,
}
);

const loadmoreStatus = computed(() => {
if (loading.value || loadingMore.value) return "loading";
if (data.value && data.value.total == 0) return "empty";
if (noMore.value) return "nomore";
return "loadmore";
});

const refreshing = ref(false);
const refreshAsync = async () => {
refreshing.value = true;
await _refreshAsync().finally(() =>
setTimeout(() => {
refreshing.value = false;
}, 200)
);
};

const loadMoreAsync = async () => {
noMore.value || _loadMoreAsync();
};

return {
dataList,
loadmoreStatus,
loadMoreAsync,
reload: _refreshAsync,
refreshAsync,
refreshing,
loading,
loadingMore,
data,
noMore,
};
};
File renamed without changes.
2 changes: 1 addition & 1 deletion layouts/default/views/main/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ watch(
}"
>
<div flex="~ col" gap="1em" overflow="hidden">
<div flex="~ col" gap="1em">
<slot />
</div>
<div
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,12 @@
"vue": "^3.4.8",
"vue-router": "^4.2.5"
},

"dependencies": {
"@types/ua-parser-js": "^0.7.39",
"@wsvaio/utils": "^1.0.22",
"jsonwebtoken": "^9.0.2",
"nodemailer": "^6.9.8",
"ua-parser-js": "^1.0.37"
"ua-parser-js": "^1.0.37",
"vue-request": "^2.0.4"
}
}
108 changes: 52 additions & 56 deletions pages/article/[id].vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,59 +4,55 @@ const id = +route.params.id;
const { data, refresh } = await useFetch<any>(`/api/article/${id}`);
useFetch(`/api/article/reads/${id}`);
useSeoMeta({
title: data.value.title,
title: data.value.title,
});
</script>

<template>
<nuxt-layout :banner-title="data.title" banner-height="38.2dvh">
<template #banner>
<ul
m="0 t-1.5em" p="0" list="none" flex="~"
gap=".5em"
>
<li flex="~">
<div class="i-material-symbols-calendar-month" />
<span>发表于 {{ new Date(data.createAt).toLocaleString() }}</span>
</li>
<li>|</li>
<li flex="~">
<div class="i-ic-twotone-update" />
<span>更新于 {{ new Date(data.updateAt).toLocaleString() }}</span>
</li>
<li>|</li>
<li flex="~">
<div class="i-carbon-category" />
<span>{{ data.type.name }}</span>
</li>
</ul>
<ul
m="0 t-1em" p="0" list="none" flex="~"
gap=".5em"
>
<li flex="~">
<div class="i-mdi-file-word-outline" />
<span>字数总计: {{ data.content.length }}</span>
</li>
<li>|</li>
<li flex="~">
<div class="i-carbon-view" />
<span>阅读量: {{ data.reads }}</span>
</li>
<li>|</li>
<li flex="~">
<div class="i-majesticons-comment-2-text-line" />
<span>评论数: {{ data.comments?.length }}</span>
</li>
</ul>
</template>
<nuxt-layout :banner-title="data.title" banner-height="38.2dvh">
<template #banner>
<ul m="0 t-1.5em" p="0" list="none" flex="~" gap=".5em">
<li flex="~">
<div class="i-material-symbols-calendar-month" />
<span>发表于 {{ new Date(data.createAt).toLocaleString() }}</span>
</li>
<li>|</li>
<li flex="~">
<div class="i-ic-twotone-update" />
<span>更新于 {{ new Date(data.updateAt).toLocaleString() }}</span>
</li>
<li>|</li>
<li flex="~">
<div class="i-carbon-category" />
<span>{{ data.type.name }}</span>
</li>
</ul>
<ul m="0 t-1em" p="0" list="none" flex="~" gap=".5em">
<li flex="~">
<div class="i-mdi-file-word-outline" />
<span>字数总计: {{ data.content.length }}</span>
</li>
<li>|</li>
<li flex="~">
<div class="i-carbon-view" />
<span>阅读量: {{ data.reads }}</span>
</li>
<li>|</li>
<li flex="~">
<div class="i-majesticons-comment-2-text-line" />
<span>评论数: {{ data.comments?.length }}</span>
</li>
</ul>
</template>

<!-- <div class="card"> -->
<markdown-preview :model-value="data.content" />
<!-- <article-copyright /> -->
<article-previous-and-next :article-id="id" />
<comments
:list="
<!-- <div class="card"> -->

<markdown-preview :model-value="data.content" />

<!-- <article-copyright /> -->
<article-previous-and-next :article-id="id" />
<comments
:list="
map(data?.comments, (item: any) => ({
...item,
id: item.id,
Expand All @@ -68,13 +64,13 @@ useSeoMeta({
}), { childrenKey: 'comments' })
"
:article-id="id"
@submit="refresh()"
/>
<!-- </div> -->
:article-id="id"
@submit="refresh()"
/>
<!-- </div> -->

<template #sub>
<catalog-card article-id="md-editor-v3-preview" />
</template>
</nuxt-layout>
<template #sub>
<catalog-card article-id="md-editor-v3-preview" />
</template>
</nuxt-layout>
</template>
52 changes: 36 additions & 16 deletions pages/index/index.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,21 @@
<script setup lang="ts">
// import BannerView from "./views/banner/index.vue";
const { dataList, loadmoreStatus, refreshing, refreshAsync, loadMoreAsync, noMore, loading } = $(
useLoadMore(async page => {
const result = await $fetch<any>("/api/article", {
query: {
page,
pageSize: 10,
},
});
return {
list: result.list,
total: result.total,
page,
};
})
);
const { data } = await useFetch<any[]>("/api/article");
const { data: message, execute: executeMessage } = await useFetch<any>("/api/common/message");
const nextMessage = () => setTimeout(() => executeMessage(), 5000);
// const { data: tags } = useLazyFetch<any[]>("/api/tag");
Expand All @@ -10,24 +24,30 @@ const nextMessage = () => setTimeout(() => executeMessage(), 5000);
// const theme = useThemeStore();
const { y } = useWindowScroll({ behavior: "smooth" });
const jump = () => {
y.value = document.documentElement.clientHeight - 48;
y.value = document.documentElement.clientHeight - 48;
};
</script>

<template>
<nuxt-layout banner-title="HI THERE">
<template #banner>
<typewriter m="1em" :content="message?.content" @finish="nextMessage" />
<div class="i-ion-ios-arrow-down arrow" @click="jump" />
</template>
<article-card v-for="(item, index) in data" :data="item" :type="index % 2 == 0 ? 'left' : 'right'" />
<template #sub>
<about-card />
<!-- <tiangou-card /> -->
</template>
</nuxt-layout>
<nuxt-layout banner-title="HI THERE">
<template #banner>
<typewriter m="1em" :content="message?.content" @finish="nextMessage" />
<div class="i-ion-ios-arrow-down arrow" @click="jump" />
</template>
<article-card v-for="(item, index) in dataList" :data="item" :type="index % 2 == 0 ? 'left' : 'right'" />
<awesome-button p="!2em" @click="loadMoreAsync" v-if="!noMore" whitespace="nowrap">
{{ loading ? "加载中" : "加载更多" }}
</awesome-button>
<!-- <div h="50vh"></div> -->
<template #sub>
<about-card />
<!-- <tiangou-card /> -->
</template>
</nuxt-layout>
</template>
<style lang="less" scoped>
Expand Down
14 changes: 14 additions & 0 deletions plugins/vue-request.client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import piniaPluginPersist from "@wsvaio/pinia-plugin-persist";
import { defineNuxtPlugin } from "#app";
import { setGlobalOptions } from "vue-request";

export default defineNuxtPlugin(nuxtApp => {
setGlobalOptions({
pagination: {
currentKey: "page",
pageSizeKey: "pageSize",
totalKey: "total",
totalPageKey: "totalPage",
},
});
});
Loading

0 comments on commit a7e9b73

Please sign in to comment.