Skip to content

Commit

Permalink
feat: 初步完成用户登录 & 鉴权流程(JWT)
Browse files Browse the repository at this point in the history
  • Loading branch information
nonhana committed Nov 23, 2024
1 parent b6d43f2 commit 5376d12
Show file tree
Hide file tree
Showing 29 changed files with 359 additions and 73 deletions.
6 changes: 4 additions & 2 deletions components/article/Category.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ const props = defineProps<{
index: number
}>()
const { data: articleData } = await useAsyncData(`articles-by-category-${props.category.name}`, () => $fetch('/api/articles/list', {
const { data } = await useFetch('/api/articles/list', {
query: { category: props.category.name, page: 1, pageSize: 6 },
}))
})
const articleData = computed(() => data.value ? data.value.payload : [])
const isFlipped = ref(false)
Expand Down
20 changes: 15 additions & 5 deletions components/article/Main.vue
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,19 @@ const displayCols = computed(() => {
const page = ref(Number(route.query.page) || 1)
const pageSize = ref(6)
const { data: total } = await useAsyncData(`article-count-${props.type}`, () => $fetch('/api/articles/count', { query: whereObj.value }))
const { data: fetchedTotal } = await useAsyncData(`articles-count-${props.type}`, () => $fetch('/api/articles/count', {
query: whereObj.value,
}), { watch: [whereObj] })
const total = computed(() => fetchedTotal.value ? fetchedTotal.value.payload ?? 0 : 0)
const { data: articleData } = await useAsyncData(`articles-by-page-${props.type}`, () => $fetch('/api/articles/list', { query: { page: page.value, pageSize: pageSize.value, ...whereObj.value } }), { watch: [query] })
const { data: fetchedArticleData } = await useAsyncData(`articles-list-${props.type}`, () => $fetch('/api/articles/list', {
query: {
page: page.value,
pageSize: pageSize.value,
...whereObj.value,
},
}), { watch: [page, pageSize, whereObj] })
const articleData = computed(() => fetchedArticleData.value ? fetchedArticleData.value.payload ?? [] : [])
watch(page, async (newPage) => {
router.replace({ query: { ...route.query, page: newPage.toString() } })
Expand All @@ -60,7 +70,7 @@ watch(() => route.query.page, (pageQuery) => {
})
const articleCards = computed<ArticleCardProps[]>(() =>
articleData.value?.map((article) => {
articleData.value.map((article) => {
return {
to: article.to,
title: article.title,
Expand All @@ -71,7 +81,7 @@ const articleCards = computed<ArticleCardProps[]>(() =>
editedAt: article.editedAt,
wordCount: article.wordCount,
}
}) || [],
}),
)
</script>

Expand All @@ -83,7 +93,7 @@ const articleCards = computed<ArticleCardProps[]>(() =>
</div>
</div>
<div class="sticky bottom-5 mx-auto mt-5 w-fit">
<HanaPaginator v-model="page" :total="total ?? 0" />
<HanaPaginator v-model="page" :total="total" />
</div>
</div>
</template>
7 changes: 4 additions & 3 deletions components/main/Body.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
<script setup lang="ts">
import type { ArticleCardProps } from '~/types/article'
const { data } = await useAsyncData('recent-articles', () => $fetch('/api/articles/list', { query: { page: 1, pageSize: 6 } }))
const { data: fetchArticleData } = await useFetch('/api/articles/list', { query: { page: 1, pageSize: 6 } })
const articleData = computed(() => fetchArticleData.value ? fetchArticleData.value.payload ?? [] : [])
const articleCards = computed<ArticleCardProps[]>(() =>
data.value?.map((article) => {
articleData.value.map((article) => {
return {
to: article.to,
title: article.title,
Expand All @@ -15,7 +16,7 @@ const articleCards = computed<ArticleCardProps[]>(() =>
editedAt: article.editedAt,
wordCount: article.wordCount,
}
}) || [],
}),
)
</script>

Expand Down
37 changes: 33 additions & 4 deletions components/main/Header/index.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
<script setup lang="ts">
import { useStore } from '~/store'
const { t } = useI18n()
const { routesMap } = useRoutesMap()
const { userStore } = useStore()
const notLoggedInMap = [{
text: t('header.user.notLoggedIn.login'),
Expand Down Expand Up @@ -58,18 +61,26 @@ function handleUserCommand(command: string | number | object) {
}
}
function handleSubmit(type: 'login' | 'register', e: Event) {
async function handleSubmit(type: 'login' | 'register', e: Event) {
switch (type) {
case 'login':
if (e.target) {
const formData = new FormData(e.target as HTMLFormElement)
console.log(Object.fromEntries(formData))
const { data } = await useFetch('/api/auth/login', { method: 'POST', body: JSON.stringify(Object.fromEntries(formData)) })
if (data.value?.success) {
localStorage.setItem('token', data.value.payload!.token)
userStore.setUserInfo(data.value.payload!.userInfo)
loginWindowVisible.value = false
}
}
break
case 'register':
if (e.target) {
const formData = new FormData(e.target as HTMLFormElement)
console.log(Object.fromEntries(formData))
const { data } = useFetch('/api/auth/register', { method: 'POST', body: JSON.stringify(Object.fromEntries(formData)) })
if (data.value?.success) {
loginWindowVisible.value = true
}
}
break
}
Expand Down Expand Up @@ -141,7 +152,7 @@ onUnmounted(() => {
class="ml-auto"
@click="changeMode"
/>
<HanaDropdown animation="slide" offset="end" :show-arrow="false" @command="handleUserCommand">
<HanaDropdown v-if="!userStore.loggedIn" animation="slide" offset="end" :show-arrow="false" @command="handleUserCommand">
<HanaButton
icon-button
icon="lucide:user-round"
Expand All @@ -160,6 +171,24 @@ onUnmounted(() => {
</HanaDropdownMenu>
</template>
</HanaDropdown>
<HanaDropdown v-if="userStore.loggedIn" animation="slide" offset="end" :show-arrow="false" @command="handleUserCommand">
<NuxtImg v-if="userStore.userInfo!.avatar" :src="userStore.userInfo!.avatar" class="size-8 cursor-pointer rounded-full" />
<div v-else class="size-8 cursor-pointer rounded-full bg-hana-blue text-center text-2xl text-white">
<span>{{ userStore.userInfo!.username[0] }}</span>
</div>
<template #dropdown>
<HanaDropdownMenu>
<HanaDropdownItem
v-for="item in loggedInMap"
:key="item.text"
:icon="item.icon"
:command="item.text"
>
{{ item.text }}
</HanaDropdownItem>
</HanaDropdownMenu>
</template>
</HanaDropdown>
</div>
</div>
</div>
Expand Down
1 change: 1 addition & 0 deletions nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ export default defineNuxtConfig({
'@nuxtjs/seo',
'@vueuse/nuxt',
'@pinia/nuxt',
'pinia-plugin-persistedstate/nuxt',
],
plugins: ['~/plugins/directives.ts'],
devtools: { enabled: true },
Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"@tailwindcss/typography": "^0.5.15",
"@types/bcrypt": "^5.0.2",
"@types/express-session": "^1.18.0",
"@types/jsonwebtoken": "^9.0.7",
"@types/node": "^22.7.4",
"@types/vivus": "^0.4.7",
"@vueuse/core": "^11.1.0",
Expand All @@ -51,8 +52,10 @@
"eslint-plugin-tailwindcss": "^3.17.4",
"express-session": "^1.18.1",
"gsap": "^3.12.5",
"jsonwebtoken": "^9.0.2",
"nuxt-lodash": "^2.5.3",
"pinia": "^2.2.5",
"pinia-plugin-persistedstate": "^4.1.3",
"prisma": "5.22.0",
"sass": "^1.79.4",
"sharp": "^0.33.5",
Expand Down
7 changes: 5 additions & 2 deletions pages/articles/archives/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@ const route = useRoute()
const router = useRouter()
// 文章总数
const { data: count } = await useAsyncData('article-count', () => $fetch('/api/articles/count'))
const { data: fetchedCount } = await useFetch('/api/articles/count')
const count = computed(() => fetchedCount.value ? fetchedCount.value.payload ?? 0 : 0)
// 文章日期,key 为年份,value 为该年份下的月份数组
const { data: dateMap } = await useAsyncData('articles-by-publishedAt', () => $fetch('/api/articles/dates'))
const { data: fetchedDataMap } = await useFetch('/api/articles/dates')
const dateMap = computed(() => fetchedDataMap.value ? fetchedDataMap.value.payload : null)
const yearList = computed(() =>
dateMap.value ? Object.keys(dateMap.value).sort((a, b) => Number(b) - Number(a)) : [],
Expand Down
4 changes: 2 additions & 2 deletions pages/articles/categories/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ definePageMeta({
name: 'categories',
})
const { data } = await useAsyncData('article-categories', () => $fetch('/api/categories/list'))
const { data: fetchedCategories } = await useFetch('/api/categories/list')
const categories = computed(() => data.value || [])
const categories = computed(() => fetchedCategories.value ? fetchedCategories.value.payload ?? [] : [])
</script>

<template>
Expand Down
4 changes: 2 additions & 2 deletions pages/articles/tags/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ definePageMeta({
name: 'tags',
})
const { data } = await useAsyncData('article-tags', () => $fetch('/api/tags/list'))
const { data: fetchedTags } = await useFetch('/api/tags/list')
const tags = computed(() => data.value || [])
const tags = computed(() => fetchedTags.value ? fetchedTags.value.payload ?? [] : [])
</script>

<template>
Expand Down
Loading

0 comments on commit 5376d12

Please sign in to comment.