Skip to content

Commit

Permalink
feat(web): filter posts by date range
Browse files Browse the repository at this point in the history
  • Loading branch information
Chilfish committed Mar 10, 2024
1 parent e22fce8 commit cfda7f9
Show file tree
Hide file tree
Showing 14 changed files with 348 additions and 87 deletions.
8 changes: 8 additions & 0 deletions apps/web/nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,16 @@ export default defineNuxtConfig({
'@pinia/nuxt',
'@nuxtjs/color-mode',
'@bg-dev/nuxt-naiveui',
'dayjs-nuxt',
],

dayjs: {
locales: ['zh-cn'],
plugins: ['timezone'],
defaultTimezone: 'Asia/Shanghai',

},

alias: {
'@core': join(root, 'packages/core/src'),
},
Expand Down
1 change: 1 addition & 0 deletions apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"@unocss/nuxt": "^0.58.5",
"@vueuse/nuxt": "^10.9.0",
"@weibo-archiver/ui": "workspace:^",
"dayjs-nuxt": "^2.1.9",
"nuxt": "^3.10.3"
}
}
6 changes: 5 additions & 1 deletion apps/web/server/api/img.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ function returnError(statusCode: number, message: string) {
}

export default defineEventHandler(async (event) => {
const { url } = getQuery<{ url: string }>(event)
const query = getQuery<{ url?: string }>(event)
const url = query.url?.trim()

if (!url)
return returnError(400, 'url is required.')

if (!url.includes('crop'))
return returnError(400, 'url should be an avatar url.')
Expand Down
2 changes: 2 additions & 0 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
},
"dependencies": {
"@vueuse/core": "^10.9.0",
"@vueuse/router": "^10.9.0",
"conf": "^12.0.0",
"dayjs": "^1.11.10",
"fuse.js": "^7.0.0",
"idb": "^8.0.0",
"ofetch": "^1.3.3",
Expand Down
1 change: 0 additions & 1 deletion packages/core/src/composables/pagination.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ export function usePagination(
page: page || 1,
pageSize: pageSize.value,
},
hash: route.hash,
})
}

Expand Down
20 changes: 18 additions & 2 deletions packages/core/src/stores/post.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ export const usePostStore = defineStore('post', () => {

const route = useRoute()

const curPage = ref(Number(route.query.page) || 1)
const pageSize = ref(Number(route.query.pageSize) || 10)
const curPage = ref(1)
const pageSize = ref(10)

const seachFn = ref<(text: string) => SaerchResult>()

Expand Down Expand Up @@ -107,6 +107,7 @@ export const usePostStore = defineStore('post', () => {

if (path === '/post') {
result = await idb.value.getDBPosts(p, pageSize.value)
total.value = totalDB.value
}
else {
const { posts, count } = await searchPost(query, p, pageSize.value)
Expand All @@ -118,6 +119,20 @@ export const usePostStore = defineStore('post', () => {
return result
}

async function getByTime(
start: number,
end: number,
page?: number,
) {
await waitIDB()

const p = page || curPage.value

const { posts, count } = await idb.value.filterByTime(start, end, p, pageSize.value)
total.value = count
return posts
}

async function updateTotal() {
await waitIDB()

Expand Down Expand Up @@ -149,5 +164,6 @@ export const usePostStore = defineStore('post', () => {
return idb.value.getPostCount()
},
updateTotal,
getByTime,
}
})
47 changes: 45 additions & 2 deletions packages/core/src/utils/storage.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { deleteDB, openDB } from 'idb'
import type { FuseResult } from 'fuse.js'
import Fuse from 'fuse.js'
import dayjs from 'dayjs'
import type { FuseResult } from 'fuse.js'
import type { DBSchema, IDBPDatabase } from 'idb'
import type { Post, UID } from '@types'

Expand Down Expand Up @@ -121,7 +122,7 @@ export class IDB {
const store = ts.store

posts.forEach((post) => {
post.created_at = new Date(post.created_at).getTime()
post.created_at = dayjs(post.created_at).valueOf()
store.put(post)
})

Expand Down Expand Up @@ -202,6 +203,48 @@ export class IDB {
},
}
}

async filterByTime(
start: number,
end: number,
page: number,
limit: number,
) {
const db = await this.idb
const posts: Post[] = []

const ts = db.transaction(STORE_NAME)

// 闭区间
const range = IDBKeyRange.bound(start, end)
const index = ts.store.index('time')
let cursor = await index.openCursor(range)

const count = await index.count(range)

if (!cursor)
return posts

try {
const target = (page - 1) * limit
target && await cursor.advance(target)

while (cursor && posts.length < limit) {
posts.push(cursor.value)
cursor = await cursor.continue()
}
ts.commit()
}
catch (e: any) {
ts.abort()
throw new Error(`Error getting posts: ${e.message}`)
}

return {
posts,
count,
}
}
}

export type SaerchResult = FuseResult<{
Expand Down
75 changes: 75 additions & 0 deletions packages/ui/src/DatePick.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<script setup lang="ts">
import dayjs from 'dayjs'
import type { Post } from '@types'
import { useRouteQuery } from '@vueuse/router'
const emits = defineEmits<{
picked: [posts: Post[]]
}>()
const page = useRouteQuery('page', 1, { transform: Number })
const pageSize = useRouteQuery('pageSize', 10, { transform: Number })
const postStore = usePostStore()
const router = useRouter()
const route = useRoute()
const now = dayjs().valueOf()
const start = ref(now)
const end = ref(now)
const dateRange = computed<[number, number]>({
get() {
return [start.value, end.value]
},
set(val) {
start.value = dayjs(val[0]).hour(0).valueOf()
end.value = dayjs(val[1]).hour(23).minute(59).second(59).valueOf()
},
})
onMounted(() => {
const query = route.query
start.value = Number(query.start) || now
end.value = Number(query.end) || now
})
async function getPosts(page = 1) {
const data = await postStore.getByTime(start.value, end.value, page)
emits('picked', data)
}
watchImmediate([start, end], async () => {
if (start.value === now)
return
await getPosts()
router.push({
query: {
...route.query,
start: start.value,
end: end.value,
},
})
})
watch([page, pageSize], async () => {
if (route.query.start)
await getPosts(page.value)
})
</script>

<template>
<div class="flex items-center gap-4">
<p class="min-w-fit">
按时间筛选
</p>
<n-date-picker
v-model:value="dateRange"
type="daterange"
size="small"
clearable
bind-calendar-months
@confirm="getPosts"
/>
</div>
</template>
5 changes: 4 additions & 1 deletion packages/ui/src/MainImage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,17 @@ const imgHost = useStorage('imgHost', '/')
watch(imgHost, () => {
realSrc.value = replaceImg(props.src)
if (!imageRef.value)
return
imgRef.value.imageRef.src = realSrc.value
imgRef.value.imageRef.parentElement.classList.remove('img-error')
})
async function setImgSrc() {
await new Promise(resolve => setTimeout(resolve, 1000))
if (!imgRef.value)
return
await new Promise(resolve => setTimeout(resolve, 1000))
const img = imgRef.value.imageRef as HTMLImageElement
const { disconnect } = lazyLoadImage([img])
Expand Down
Loading

0 comments on commit cfda7f9

Please sign in to comment.