college-list.vue 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. <template>
  2. <view class="h-full">
  3. <z-paging ref="paging" v-model="list" @query="handleQuery">
  4. <template #top>
  5. <slot name="top" />
  6. <college-conditions-picker v-if="filterOptions" :options="filterOptions" :absolute="absolute" @change="handleSearch" />
  7. <ie-search v-model="queryParams.name" placeholder="输入院校名称" @search="handleSearch" @clear="handleSearch" />
  8. </template>
  9. <view class="p-20 flex flex-col gap-20">
  10. <college-item v-for="i in list" :key="i.code" :item="i" @click="handleDetail(i)" />
  11. </view>
  12. </z-paging>
  13. </view>
  14. </template>
  15. <script setup lang="ts">
  16. import { useTransferPage } from "@/hooks/useTransferPage";
  17. import { getUniversityFilters, universityList } from "@/api/modules/university";
  18. import type { University, UniversityQueryDto, UniversityFilter } from "@/types/university";
  19. import { UNIVERSITY_FILTER } from "@/types/injectionSymbols";
  20. import CollegeConditionsPicker from "@/pagesOther/pages/university/index/components/plus/college-conditions-picker.vue";
  21. import CollegeItem from "@/pagesOther/pages/university/index/components/plus/college-item.vue";
  22. import { routes } from "@/common/routes";
  23. const props = withDefaults(defineProps<{
  24. customItemClick?: boolean;
  25. extraFilter?: Record<string, any>;
  26. absolute?: boolean;
  27. }>(), {
  28. customItemClick: false,
  29. extraFilter: () => ({})
  30. })
  31. const emits = defineEmits(['item-click'])
  32. const { prevData, transferTo } = useTransferPage()
  33. const paging = ref<ZPagingInstance>()
  34. const list = ref<University[]>([])
  35. const filterOptions = ref<UniversityFilter | null>(null)
  36. const queryParams = ref<UniversityQueryDto>({
  37. name: '',
  38. features: [],
  39. type: [],
  40. natureTypeCN: [],
  41. location: [],
  42. level: [],
  43. tier: []
  44. })
  45. const handleSearch = async () => {
  46. paging.value?.reload();
  47. }
  48. const handleQuery = (pageNum: number, pageSize: number) => {
  49. const filterParams: Record<string, string> = {};
  50. Object.keys(queryParams.value).forEach(item => {
  51. const value = queryParams.value[item as keyof UniversityQueryDto]
  52. filterParams[item] = Array.isArray(value) ? value.join(',') : value
  53. });
  54. const query = { pageNum, pageSize, ...props.extraFilter, ...filterParams }
  55. universityList(query)
  56. .then(res => paging.value?.completeByTotal(res.rows, res.total))
  57. .catch(e => paging.value?.complete(false))
  58. }
  59. const handleDetail = (u: University) => {
  60. if (props.customItemClick) {
  61. return emits('item-click', u)
  62. }
  63. const { id, code, name } = u
  64. transferTo(routes.universityDetail, { data: { id, code, name } })
  65. }
  66. provide(UNIVERSITY_FILTER, queryParams)
  67. onMounted(async () => {
  68. const { data } = await getUniversityFilters()
  69. filterOptions.value = data
  70. // accept default query parameters
  71. if (prevData.value.tier) {
  72. queryParams.value.tier = [prevData.value.tier]
  73. }
  74. });
  75. </script>
  76. <style scoped></style>