feat: 志愿表筛选

master
xjs 2025-03-17 13:11:58 +08:00
parent 840dd36f7e
commit e3977c7e89
10 changed files with 151 additions and 65 deletions

View File

@ -3,20 +3,22 @@
<view
class="action-sheet-mask"
:class="{ 'action-sheet-mask-show': show }"
@click="handleClose"
@click.stop="handleClose"
@touchmove.prevent
></view>
<view class="action-sheet pb-safe" :class="{ 'action-sheet-show': show }" @touchmove.prevent>
<view class="action-sheet-header" v-if="title">
<text class="action-sheet-title">{{ title }}</text>
</view>
<slot name="title"></slot>
<scroll-view class="action-sheet-content" :scroll-y="true">
<slot></slot>
</scroll-view>
<view class="action-sheet-footer" v-if="$slots.footer">
<slot name="footer"></slot>
</view>
<template v-if="!lazyRender || show">
<view class="action-sheet-header" v-if="title">
<text class="action-sheet-title">{{ title }}</text>
</view>
<slot name="title"></slot>
<scroll-view class="action-sheet-content" :scroll-y="true">
<slot></slot>
</scroll-view>
<view class="action-sheet-footer" v-if="$slots.footer">
<slot name="footer"></slot>
</view>
</template>
</view>
</view>
</template>
@ -25,6 +27,7 @@
defineProps<{
show: boolean
title?: string
lazyRender?: boolean
}>()
const emit = defineEmits<{
@ -44,7 +47,7 @@ const handleClose = () => {
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
z-index: 999;
z-index: 9;
opacity: 0;
visibility: hidden;
transition: all 0.3s ease;

View File

@ -11,7 +11,7 @@
>
{{ calcTypeName(major.type).text }}
</view>
<text class="text-[32rpx] font-semibold text-[#000]">{{ major.percentAge }}%</text>
<text class="text-[32rpx] font-semibold text-[#000]">{{ major.percentAge || '0%' }}</text>
</view>
<view class="flex flex-col gap-[16rpx]">
<view class="flex justify-between flex-auto">
@ -19,6 +19,7 @@
<text class="text-[32rpx] text-[#000] font-semibold truncate max-w-[400rpx]">
{{ major.major.replace(/(\r\n|\n|\r)/g, '') }}
</text>
<text class="text-[22rpx] text-[#1F2329] mt-[14rpx]">{{ major.remark }}</text>
<view class="flex justify-between text-[22rpx] text-[#1F2329] mt-[14rpx]">
<view class="flex flex-col gap-[6rpx]">
<text>代码{{ major.majorCode }}</text>
@ -32,10 +33,10 @@
</view>
<view
class="w-[104rpx] h-[52rpx] rounded-[8rpx] custom-btn"
:class="`w-[104rpx] h-[52rpx] rounded-[8rpx] text-[24rpx] custom-btn ${checkActive(major) ? 'active-btn' : ''}`"
@click.stop="handleClick(major)"
>
填报
{{ checkActive(major) ? '已填报' : '填报' }}
</view>
</view>
<DataTable :data="major.items" :score="score" />
@ -57,7 +58,10 @@ const props = defineProps<{
const handleClick = (major: any) => {
let exitMajorUnList = userStore.userInfo.wishList.find((item) => item.unId === props.item.uId)
if (exitMajorUnList) {
let exitMajor = exitMajorUnList?.vItems.find((item) => item._pId === major.planId)
if (exitMajor) {
userStore.deleteWishListMajor({ unId: props.item.uId, _pId: major.planId })
} else if (exitMajorUnList) {
userStore.setWishListMajor({
val: {
_pId: major.planId,
@ -89,6 +93,17 @@ const handleClick = (major: any) => {
userStore.setWishListMajorWithUn(_major)
}
}
const checkActive = (major: unknown) => {
const _major = major as { planId: string }
return userStore.userInfo.wishList.find((item) => {
if (item.unId !== props.item.uId) {
return false
} else if (item.vItems.find((vItem) => vItem._pId === _major.planId)) {
return true
}
})
}
</script>
<style lang="scss" scoped>
@ -103,4 +118,9 @@ const handleClick = (major: any) => {
align-items: center;
justify-content: center;
}
.active-btn {
background-color: #1580ff;
color: #fff;
}
</style>

View File

@ -45,14 +45,16 @@
>
专业{{ item.items.length }}
</view>
<text class="text-[20rpx] text-[#8F959E]">已填 1</text>
<text class="text-[20rpx] text-[#8F959E]" v-if="collegeMajorCount > 0">
已填 {{ collegeMajorCount }}
</text>
</view>
</view>
<DataTable :data="item.childItems" v-bind="$attrs" />
</view>
</view>
<ActionSheet v-model:show="show">
<ActionSheet v-model:show="show" :lazy-render="true">
<template #title>
<view class="flex items-center justify-between px-[32rpx] pt-[32rpx] pb-[24rpx]">
<view class="flex flex-col gap-[14rpx]">
@ -65,7 +67,7 @@
<view class="i-carbon-close-large w-[40rpx] h-[40rpx]" @click.stop="show = false"></view>
<view class="text-[22rpx]">
<text>已填</text>
<text class="text-[#1580FF]">2</text>
<text class="text-[#1580FF]">{{ majorCount }}</text>
<text></text>
</view>
</view>
@ -94,6 +96,7 @@ const userStore = useUserStore()
const props = defineProps({
item: Object,
majorCount: Number,
})
const show = ref(false)
@ -104,6 +107,12 @@ const handleConfirm = () => {
const handleShow = () => {
show.value = true
}
const collegeMajorCount = computed(() => {
return (
userStore.userInfo.wishList.find((item) => item.unId === props.item.uId)?.vItems.length || 0
)
})
</script>
<style lang="scss" scoped>

View File

@ -51,8 +51,8 @@
<Slider
v-model:modelValue="sliderValue"
:min="500"
:max="600"
:min="minScore"
:max="maxScore"
:step="1"
:range="true"
@change="handleSliderChange"
@ -67,47 +67,48 @@
:id="`zp-id-${item.zp_index}`"
:key="item.zp_index"
v-for="(item, index) in schoolList"
@click="itemClick(item, index)"
>
<ScrollListItem :item="item" :score="score" />
<ScrollListItem :item="item" :score="score" :major-count="majorCount" />
</view>
<ActionSheet v-model:show="show" :title="actionTitle">
<view class="px-[36rpx]">
<Region
v-if="actionType === 2"
width="210rpx"
height="60rpx"
class="px-[32rpx]"
@change-name="handleRegionName"
/>
</view>
<FilterMenu v-if="actionType === 1" :show-phase="false" ref="filterMenuRef" :menuBit="28" />
<CustomPickerView
v-if="actionType === 3"
:list="typeModelList"
v-model:modelValue="collegeSearch.tModelValue"
value-key="value"
label-key="name"
@change="handleTypeModelChange"
/>
<template #footer>
<view class="flex items-center justify-between gap-[30rpx]">
<view class="cancel-btn" @click="show = false">取消</view>
<view class="submit-btn" @click="handleConfirm"></view>
</view>
</template>
</ActionSheet>
<template #bottom>
<view class="pb-safe px-[32rpx] pt-[32rpx] bg-[#fff]">
<view
class="h-[80rpx] rounded-[8rpx] bg-[#1580FF] flex items-center justify-center text-[#fff]"
:class="`h-[80rpx] rounded-[8rpx] bg-[#1580FF] flex items-center justify-center text-[#fff] ${majorCount === 0 ? 'disabled-btn' : ''}`"
@click="handlePreview"
>
预览志愿表(2)
预览志愿表({{ majorCount }})
</view>
</view>
</template>
</z-paging>
<ActionSheet v-model:show="show" :title="actionTitle">
<view class="px-[36rpx]">
<Region
v-if="actionType === 2"
width="210rpx"
height="60rpx"
class="px-[32rpx]"
@change-name="handleRegionName"
/>
</view>
<FilterMenu v-if="actionType === 1" :show-phase="false" ref="filterMenuRef" :menuBit="28" />
<CustomPickerView
v-if="actionType === 3"
:list="typeModelList"
v-model:modelValue="collegeSearch.tModelValue"
value-key="value"
label-key="name"
@change="handleTypeModelChange"
/>
<template #footer>
<view class="flex items-center justify-between gap-[30rpx]">
<view class="cancel-btn" @click="show = false">取消</view>
<view class="submit-btn" @click="handleConfirm"></view>
</view>
</template>
</ActionSheet>
</template>
<script lang="ts" setup>
@ -117,7 +118,7 @@ import Region from '@/pages-sub/home/components/Region.vue'
import FilterMenu from '@/pages-sub/home/components/FilterMenu.vue'
import Slider from '@/pages-sub/components/Slider.vue'
import CustomPickerView from '@/pages-sub/components/CustomPickerView.vue'
import { getBatchData } from '@/service/index/api'
import { getBatchBase } from '@/service/index/api'
import ScrollListItem from './ScrollListItem.vue'
import HeaderTip from './HeaderTip.vue'
@ -142,6 +143,10 @@ const handleTypeModelChange = ({ item }) => {
collegeSearch.value.tModel = item.name
}
const majorCount = computed(() => {
return userStore.userInfo.wishList.reduce((a, b) => a + b.vItems.length, 0)
})
const queryList = (page: number, pageSize: number) => {
getPlanProListByFilter({
pageIndex: page,
@ -158,6 +163,7 @@ const queryList = (page: number, pageSize: number) => {
feature: collegeSearch.value.feature,
majors: collegeSearch.value.majors,
keyword: searchValue.value,
type: collegeSearch.value.tModelValue === '-1' ? null : +collegeSearch.value.tModelValue,
}).then((resp) => {
if (resp.code === 200) {
paging.value.complete((resp.result as { rows: any[] }).rows)
@ -219,25 +225,38 @@ const handleRegionName = (val: string[]) => {
province.value = val
}
const sliderValue = ref([550, 590])
const sliderValue = ref([
+userStore.userInfo.estimatedAchievement.expectedScore - 50,
+userStore.userInfo.estimatedAchievement.expectedScore + 50,
])
const handleSliderChange = (val) => {
paging.value.reload()
}
const score = ref(0)
const minScore = ref(0)
const maxScore = ref(0)
onLoad(() => {
getBatchData(userStore.userInfo.batchDataUrl).then((resp) => {
if (resp.code === 200) {
const _batchData = resp.result as any[]
if (_batchData.length > 0) {
const _score =
_batchData[0].batches.find((item) => item.batch === userStore.userInfo.batchName)
?.score || 0
score.value = _score
getBatchBase({ locationCode: userStore.userInfo.estimatedAchievement.provinceCode }).then(
(resp) => {
if (resp.code === 200) {
const _result = resp.result as { batches: any[]; maxScore: number; minScore: number }
if (_result.batches.length > 0) {
const _score =
_result.batches.find((item) => item.batch === userStore.userInfo.batchName)?.score || 0
score.value = _score
}
minScore.value = _result.minScore
maxScore.value = _result.maxScore
}
}
})
},
)
})
const handlePreview = () => {
uni.navigateTo({ url: '/pages-sub/home/wishesList/wishesList' })
}
</script>
<style lang="scss" scoped>
@ -250,4 +269,9 @@ onLoad(() => {
.border-top {
border-top: 2rpx solid #ededed;
}
.disabled-btn {
background-color: #f5f5f5 !important;
color: #999 !important;
}
</style>

View File

@ -1,6 +1,6 @@
export const calcTypeName = (type: number) => {
const style = {
0: {
2: {
text: '冲',
color: '#EB5241',
bgColor: 'rgba(235,82,65,0.15)',
@ -10,7 +10,7 @@ export const calcTypeName = (type: number) => {
color: '#FA8E23',
bgColor: 'rgba(250,142,35,0.15)',
},
2: {
0: {
text: '保',
color: '#15C496',
bgColor: 'rgba(21,196,150,0.15)',

View File

@ -0,0 +1,11 @@
<template>
<view class="">
<HeaderTip :user-info="userStore.userInfo" />
</view>
</template>
<script setup lang="ts">
import { useUserStore } from '@/store/user'
const userStore = useUserStore()
</script>

View File

@ -261,6 +261,10 @@
{
"path": "home/wishesList/ScrollListItem",
"type": "page"
},
{
"path": "home/wishesList/wishesList",
"type": "page"
}
]
},

View File

@ -276,3 +276,7 @@ export const aiPreview = (params: {
export const getPlanProListByFilter = (params: AutoFillParams) => {
return http.post('/api/PlanPro/aiUniversity', params)
}
export const getBatchBase = (params: { locationCode: string }) => {
return http.get('/api/busBatchBase/batch', params)
}

View File

@ -143,6 +143,15 @@ export const useUserStore = defineStore(
}
}
const deleteWishListMajor = ({ unId, _pId }: { unId: string; _pId: string }) => {
userInfo.value.wishList = userInfo.value.wishList.map((item) => {
if (item.unId === unId) {
item.vItems = item.vItems.filter((vItem) => vItem._pId !== _pId)
return item
}
return item
})
}
const setWishListMajorWithUn = (val) => {
userInfo.value.wishList.push({ ...val, sort: userInfo.value.wishList.length + 1 })
}
@ -181,6 +190,7 @@ export const useUserStore = defineStore(
clearWishList,
setWishListMajor,
setWishListMajorWithUn,
deleteWishListMajor,
}
},
{

View File

@ -32,6 +32,7 @@ interface NavigateToOptions {
"/pages-sub/home/wishesList/HeaderTip" |
"/pages-sub/home/wishesList/index" |
"/pages-sub/home/wishesList/ScrollListItem" |
"/pages-sub/home/wishesList/wishesList" |
"/login-sub/index" |
"/pages-evaluation-sub/index" |
"/pages-evaluation-sub/aiAutoFill/index" |