Skip to content

Commit

Permalink
feat: enhance student list sorting and filtering
Browse files Browse the repository at this point in the history
- Implement advanced birthday sorting
- Refactor data processing logic in App.vue for more efficient filtering and sorting
  • Loading branch information
U1805 committed Jan 27, 2025
1 parent 873a69d commit 000e6a2
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 40 deletions.
73 changes: 35 additions & 38 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -119,10 +119,11 @@ import { RouterLink, RouterView } from 'vue-router'
import i18n from '@/locales/i18n'
import { baseStudent, studentInfo } from '@/assets/requestUtils/interface'
import { getStudents, getSchoolIcon } from '@/assets/requestUtils/request'
import { birthday_sort, SupportedLanguage } from '@/assets/requestUtils/dateFormat'
import { download } from '@/assets/imgUtils/download'
import { store } from '@/assets/storeUtils/store'
import { talkHistory } from '@/assets/storeUtils/talkHistory'
import { search, debounce } from '@/assets/utils/search'
import { debounce, search } from '@/assets/utils/search'
import Popper from 'vue3-popper'
store.getData()
Expand All @@ -139,10 +140,10 @@ const dataDisplay = ref<studentInfo[]>(database.value)
const showPopper = ref<boolean>(false)
const filter_condition = ref(
{
sort_type: '', // 排序类型 名字 生日 学校 社团
sort_asc: true, // 排序顺序 true 升序 false 降序
filter_star: 0, // 稀有度 0 1 2 3
filter_released: true, // 已实装 true false
sort_type: '', // 排序类型 名字 生日 学校 社团
sort_asc: true, // 排序顺序 true 升序 false 降序
filter_star: 0, // 稀有度 0 1 2 3
filter_released: true, // 已实装 true false
}
)
const filter_condition_copy = ref(filter_condition.value)
Expand All @@ -161,40 +162,36 @@ const popperConfirm = () => {
const searchText = ref<string>('')
const searchSchool = ref<string>('')
const dataFilter = () => {
dataDisplay.value = database.value.filter((item) => {
if (filter_condition.value.filter_star > 0 && item.Star !== filter_condition.value.filter_star) return false
if (item.Released !== filter_condition.value.filter_released) return false
return true
})
}
const dataSort = () => {
if (filter_condition.value.sort_type === '') {
if (!filter_condition.value.sort_asc) dataDisplay.value = dataDisplay.value.reverse()
return
}
dataDisplay.value = dataDisplay.value.sort((a, b) => {
// TODO: if sort_type == "Birthday"
// student who has birthday today(or in 3 days) will be at the top, and her school will be show as a birthday cake icon
const aValue = a[filter_condition.value.sort_type as keyof studentInfo] as string
const bValue = b[filter_condition.value.sort_type as keyof studentInfo] as string
return filter_condition.value.sort_asc ?
aValue.localeCompare(bValue) :
bValue.localeCompare(aValue)
})
}
const dataSearch = debounce(() => {
dataDisplay.value = search(
dataDisplay.value,
searchText.value,
searchSchool.value
)
const processData = debounce(() => {
dataDisplay.value = database.value
// filter
.filter(item => {
if (filter_condition.value.filter_star > 0 && item.Star !== filter_condition.value.filter_star) return false
if (item.Released !== filter_condition.value.filter_released) return false
return true
})
// search
.filter(item => search([item], searchText.value, searchSchool.value).length > 0)
// sort
.sort((a, b) => {
if (filter_condition.value.sort_type === '') {
return filter_condition.value.sort_asc ? 0 : -1
}
if (filter_condition.value.sort_type === 'Birthday') {
return filter_condition.value.sort_asc ?
birthday_sort(a, b, store.language as SupportedLanguage) :
birthday_sort(b, a, store.language as SupportedLanguage)
}
const aValue = a[filter_condition.value.sort_type as keyof studentInfo] as string
const bValue = b[filter_condition.value.sort_type as keyof studentInfo] as string
return filter_condition.value.sort_asc ?
aValue.localeCompare(bValue) :
bValue.localeCompare(aValue)
})
}, 300) // 防抖
const processData = () => {
dataFilter()
dataSearch()
dataSort()
}
processData()
watch(filter_condition, () => {
processData()
Expand Down
57 changes: 56 additions & 1 deletion src/assets/requestUtils/dateFormat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const getOrdinalSuffix = (day: number): string => {
}

export const dateFormat = (birthday: string, lng: SupportedLanguage) => {
if (!birthday) return '???'
if (!birthday || !/^\d+\/\d+$/.test(birthday)) return '???'
const TOOL = {
zh: (month: number, day: number) => `${month}${day}日`,
tw: (month: number, day: number) => `${month}${day}日`,
Expand All @@ -29,3 +29,58 @@ export const dateFormat = (birthday: string, lng: SupportedLanguage) => {
const [month, day] = birthday.split('/').map(Number)
return TOOL[lng](month, day)
}

export const dateFormatReverse = (date: string, lng: SupportedLanguage): string => {
if (!date) return ''

const parseDate = {
zh: (str: string) => {
const nums = str.match(/\d+/g)?.map(Number)
return nums?.length === 2 ? nums : null
},
tw: (str: string) => parseDate.zh(str),
jp: (str: string) => parseDate.zh(str),
kr: (str: string) => parseDate.zh(str),
en: (str: string) => {
const monthName = MONTHS_EN.find(m => str.toLowerCase().includes(m.toLowerCase()))
if (!monthName) return null
const month = MONTHS_EN.indexOf(monthName) + 1
const day = parseInt(str.match(/\d+/)?.[0] || '')
return [month, day]
}
}

const [month, day] = parseDate[lng](date) || []

if (!month || !day || month < 1 || month > 12 || day < 1 || day > 31) {
return ''
}

return `${month}/${day}`
}

export const birthday_sort = (a: any, b: any, lng: SupportedLanguage) => {
// 将 MM/DD 格式转换为今年的日期以进行比较
const today = new Date()
const currentYear = today.getFullYear()

const getDateFromBirthday = (birthday: string) => {
birthday = dateFormatReverse(birthday, lng)
if (!birthday) {
const yesterday = new Date()
yesterday.setDate(yesterday.getDate() - 1)
return yesterday
}
const [month, day] = birthday.split('/').map(Number)
return new Date(currentYear, month - 1, day - 1)
}

const aDate = getDateFromBirthday(a.Birthday)
const bDate = getDateFromBirthday(b.Birthday)

// 如果日期已经过了,使用明年的日期
if (aDate < today) aDate.setFullYear(currentYear + 1)
if (bDate < today) bDate.setFullYear(currentYear + 1)

return aDate.getTime() - bDate.getTime()
}
3 changes: 2 additions & 1 deletion src/assets/utils/search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ const search = (data: studentInfo[], key: string, filter: string) => {
if (!processedKey && !processedFilter) return data

return data.filter(item => {
if (!processedKey) return processString(item.School).includes(processedFilter)
if (processedFilter && !processString(item.School).includes(processedFilter)) return false
if (!processedKey) return true

// 检查名字(简体、繁体、拼音)
const name = processString(item.Name)
Expand Down

0 comments on commit 000e6a2

Please sign in to comment.