feat: 自愿表

master
xjs 2025-03-13 18:00:37 +08:00
parent 7a3e90e9db
commit 3c753725db
33 changed files with 895 additions and 169 deletions

View File

@ -1,28 +0,0 @@
<template>
<wd-fab :draggable="true" :expandable="false" :gap="{ bottom: 100 }">
<template #trigger>
<view class="btn-wrapper" @click="handleClick">
<image
class="w-full h-full rounded-full"
src="/static/images/home/customerService.svg"
></image>
</view>
</template>
</wd-fab>
</template>
<script lang="ts" setup>
const handleClick = () => {
uni.navigateTo({
url: '/pages-sub/customerService/index/index',
})
}
</script>
<style lang="scss" scoped>
.btn-wrapper {
width: 128rpx;
height: 128rpx;
border-radius: 50%;
}
</style>

View File

@ -127,8 +127,14 @@ const getUserInfo = async (code: string) => {
const infoData = resp.result as unknown as {
userExtend: { provinceCode: string }
zyBatches: any[]
batchDataUrl: string
batchName: string
}
userStore.setEstimatedAchievement(infoData.userExtend)
userStore.setZyBatches(infoData.zyBatches)
userStore.setBatchDataUrl(infoData.batchDataUrl)
userStore.setBatchName(infoData.batchName)
if (resp.code === 200) {
//
getVolunteerInitialization().then((res) => {

View File

@ -1,6 +1,5 @@
<route lang="json5" type="page">
{
layout: 'page',
style: {
navigationStyle: 'custom',
},

View File

@ -86,9 +86,6 @@ const currentIndex = computed(() => {
if (!props.modelValue || !props.list.length) return [0]
let targetValue = props.modelValue
if (typeof props.list[0] === 'object' && props.valueKey) {
targetValue = props.modelValue[props.valueKey]
}
const index = props.list.findIndex((item) => {
if (typeof item === 'object' && props.valueKey) {

View File

@ -0,0 +1,422 @@
<template>
<view class="wd-slider-wrapper">
<view class="wd-slider">
<view class="wd-slider-rail"></view>
<view
class="wd-slider-track"
:style="{
left: range ? `${leftPercentage}%` : '0%',
width: range ? `${rightPercentage - leftPercentage}%` : `${rightPercentage}%`,
backgroundColor: activeColor,
}"
></view>
<view
v-if="range"
class="wd-slider-thumb left-thumb"
:class="{ 'active-thumb': isLeftActive }"
:style="{
left: `${leftPercentage}%`,
transform: 'translate(-50%, -50%)',
borderColor: activeColor,
}"
@touchstart="handleLeftThumbTouchStart"
@touchmove="handleLeftThumbTouchMove"
@touchend="handleLeftThumbTouchEnd"
>
<text
v-if="showThumbValue || isLeftActive"
class="wd-slider-thumb-value-inner"
:class="{ 'active-value': isLeftActive }"
:style="{ color: computedThumbValueColor }"
>
{{ formatValue(currentLeftValue) }}
</text>
</view>
<view
class="wd-slider-thumb right-thumb"
:class="{ 'active-thumb': isRightActive }"
:style="{
left: `${rightPercentage}%`,
transform: 'translate(-50%, -50%)',
borderColor: activeColor,
}"
@touchstart="handleRightThumbTouchStart"
@touchmove="handleRightThumbTouchMove"
@touchend="handleRightThumbTouchEnd"
>
<text
v-if="showThumbValue || isRightActive"
class="wd-slider-thumb-value-inner"
:class="{ 'active-value': isRightActive }"
:style="{ color: computedThumbValueColor }"
>
{{ formatValue(currentRightValue) }}
</text>
</view>
</view>
<view v-if="showLabels" class="wd-slider-labels">
<text class="wd-slider-label left-label">{{ formatValue(currentLeftValue) }}</text>
<text class="wd-slider-label right-label">{{ formatValue(currentRightValue) }}</text>
</view>
</view>
</template>
<script setup>
import { ref, computed, watch, onMounted, onBeforeUnmount } from 'vue'
import { getCurrentInstance } from 'vue'
//
const instance = getCurrentInstance()
const props = defineProps({
modelValue: {
type: Array,
default: () => [0, 0],
},
min: {
type: Number,
default: 0,
},
max: {
type: Number,
default: 100,
},
step: {
type: Number,
default: 1,
},
range: {
type: Boolean,
default: false,
},
showLabels: {
type: Boolean,
default: false,
},
showThumbValue: {
type: Boolean,
default: true,
},
activeColor: {
type: String,
default: '#4e80ff',
},
thumbValueColor: {
type: String,
default: '',
},
disabled: {
type: Boolean,
default: false,
},
formatValue: {
type: Function,
default: (value) => {
//
if (typeof value === 'number') {
if (value < 10) {
return value.toFixed(1)
}
}
return value
},
},
})
const emit = defineEmits(['update:modelValue', 'change'])
//
const currentLeftValue = ref(props.range ? props.modelValue[0] : props.min)
const currentRightValue = ref(props.range ? props.modelValue[1] : props.modelValue[0])
//
const isLeftActive = ref(false)
const isRightActive = ref(false)
//
const railWidth = ref(0)
//
const computedThumbValueColor = computed(() => {
return props.thumbValueColor || props.activeColor
})
//
const initRailWidth = () => {
setTimeout(() => {
getRailWidth().then((width) => {
railWidth.value = width
})
}, 100) // DOM
}
//
onMounted(() => {
initRailWidth()
//
uni.onWindowResize(initRailWidth)
})
//
onBeforeUnmount(() => {
uni.offWindowResize(initRailWidth)
})
//
const leftPercentage = computed(() => {
return ((currentLeftValue.value - props.min) / (props.max - props.min)) * 100
})
const rightPercentage = computed(() => {
return ((currentRightValue.value - props.min) / (props.max - props.min)) * 100
})
//
watch(
() => props.modelValue,
(newVal) => {
if (props.range) {
currentLeftValue.value = newVal[0]
currentRightValue.value = newVal[1]
} else {
currentRightValue.value = newVal[0]
}
},
{ immediate: true, deep: true },
)
//
const calculateValueFromPosition = (position, width) => {
const percentage = Math.max(0, Math.min(100, (position / width) * 100))
const rawValue = (percentage / 100) * (props.max - props.min) + props.min
//
const steps = Math.round((rawValue - props.min) / props.step)
return props.min + steps * props.step
}
//
let startX = 0
let startLeftValue = 0
let startRightValue = 0
let isDragging = false
//
const getRailWidth = () => {
return new Promise((resolve) => {
const query = uni.createSelectorQuery()
if (instance) {
query.in(instance.proxy)
}
query
.select('.wd-slider-rail')
.boundingClientRect((data) => {
if (data) {
resolve(data.width)
} else {
resolve(0)
}
})
.exec()
})
}
const handleLeftThumbTouchStart = async (e) => {
if (props.disabled) return
isDragging = true
isLeftActive.value = true
startX = e.touches[0].clientX
startLeftValue = currentLeftValue.value
// 使
if (!railWidth.value) {
railWidth.value = await getRailWidth()
}
}
const handleLeftThumbTouchMove = (e) => {
if (!isDragging || props.disabled || !railWidth.value) return
const moveX = e.touches[0].clientX - startX
const movePercentage = (moveX / railWidth.value) * 100
const newLeftValue = calculateValueFromPosition(
((startLeftValue - props.min) / (props.max - props.min)) * railWidth.value + moveX,
railWidth.value,
)
//
if (newLeftValue <= currentRightValue.value) {
currentLeftValue.value = newLeftValue
emitValueChange()
}
}
const handleLeftThumbTouchEnd = () => {
if (props.disabled) return
isDragging = false
isLeftActive.value = false
emit(
'change',
props.range ? [currentLeftValue.value, currentRightValue.value] : [currentRightValue.value],
)
}
const handleRightThumbTouchStart = async (e) => {
if (props.disabled) return
isDragging = true
isRightActive.value = true
startX = e.touches[0].clientX
startRightValue = currentRightValue.value
// 使
if (!railWidth.value) {
railWidth.value = await getRailWidth()
}
}
const handleRightThumbTouchMove = (e) => {
if (!isDragging || props.disabled || !railWidth.value) return
const moveX = e.touches[0].clientX - startX
const movePercentage = (moveX / railWidth.value) * 100
const newRightValue = calculateValueFromPosition(
((startRightValue - props.min) / (props.max - props.min)) * railWidth.value + moveX,
railWidth.value,
)
//
if (props.range) {
if (newRightValue >= currentLeftValue.value) {
currentRightValue.value = newRightValue
emitValueChange()
}
} else {
currentRightValue.value = newRightValue
emitValueChange()
}
}
const handleRightThumbTouchEnd = () => {
if (props.disabled) return
isDragging = false
isRightActive.value = false
emit(
'change',
props.range ? [currentLeftValue.value, currentRightValue.value] : [currentRightValue.value],
)
}
//
const emitValueChange = () => {
emit(
'update:modelValue',
props.range ? [currentLeftValue.value, currentRightValue.value] : [currentRightValue.value],
)
}
</script>
<style lang="scss" scoped>
.wd-slider-wrapper {
box-sizing: border-box;
width: 100%;
}
.wd-slider {
position: relative;
height: 30px;
display: flex;
align-items: center;
}
.wd-slider-rail {
position: absolute;
width: 100%;
height: 4px;
background-color: #e9e9e9;
border-radius: 2px;
}
.wd-slider-track {
position: absolute;
height: 4px;
background-color: v-bind('activeColor');
border-radius: 2px;
}
.wd-slider-thumb {
position: absolute;
width: 66rpx;
height: 42rpx;
border-radius: 12rpx 12rpx 12rpx 12rpx;
background-color: #fff;
border: 2px solid v-bind('activeColor');
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
z-index: 1;
top: 50%;
transition:
transform 0.2s,
width 0.2s,
height 0.2s,
background-color 0.2s;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
user-select: none;
}
.active-thumb {
transform: translate(-50%, -50%) scale(0.7) !important;
z-index: 2;
border-color: v-bind('activeColor');
background-color: #f5f8ff;
width: 42px;
height: 42px;
}
.wd-slider-thumb-value-inner {
font-size: 12px;
color: v-bind('computedThumbValueColor');
text-align: center;
transition: all 0.2s;
line-height: 1;
font-weight: 500;
white-space: nowrap; /* 防止数字换行 */
padding: 0 2px;
}
.active-value {
font-weight: bold;
color: v-bind('computedThumbValueColor');
font-size: 13px;
}
.wd-slider-labels {
display: flex;
justify-content: space-between;
margin-top: 10px;
font-size: 12px;
color: #666;
}
.wd-slider-label {
transform: translateX(-50%);
}
.left-label {
position: relative;
left: v-bind(leftPercentage + '%');
}
.right-label {
position: relative;
left: v-bind(rightPercentage + '%');
}
</style>

View File

@ -109,7 +109,7 @@ const checkboxStyle = computed(() => {
display: flex;
flex-wrap: wrap;
gap: 16rpx;
padding: 32rpx 16rpx 16rpx;
// padding: 32rpx 16rpx 16rpx;
}
:deep(.checkbox-active) {

View File

@ -1,6 +1,5 @@
<route lang="json5" type="page">
{
layout: 'page',
style: {
navigationStyle: 'custom',
},

View File

@ -1,6 +1,5 @@
<route lang="json5" type="page">
{
layout: 'page',
style: {
navigationStyle: 'custom',
},

View File

@ -1,6 +1,5 @@
<route lang="json5" type="page">
{
layout: 'page',
style: {
navigationStyle: 'custom',
},
@ -34,7 +33,14 @@
src="@/pages-sub/static/images/autoFill/auto-fill.jpg"
></image>
</view>
<FilterMenu v-model:show="show" />
<ActionSheet
v-model:show="show"
title="筛选"
@close="close"
custom-header-class="text-[36rpx]! text-[#303030]! font-medium!"
>
<FilterMenu />
</ActionSheet>
</view>
</template>
@ -42,6 +48,7 @@
import FilterMenu from '@/pages-sub/home/components/FilterMenu.vue'
import Navbar from '@/pages-sub/components/navbar/Navbar.vue'
import Badge from '@/pages-sub/components/badge/Badge.vue'
import ActionSheet from '@/pages-sub/components/ActionSheet.vue'
import { ref } from 'vue'
const navigatorBack = () => {
@ -50,6 +57,10 @@ const navigatorBack = () => {
const show = ref(false)
const badgeValue = ref(12)
const close = () => {
show.value = false
}
</script>
<style lang="scss" scoped>

View File

@ -1,6 +1,5 @@
<route lang="json5" type="page">
{
layout: 'page',
style: {
navigationStyle: 'custom',
},

View File

@ -1,6 +1,5 @@
<route lang="json5" type="page">
{
layout: 'page',
style: {
navigationStyle: 'custom',
},

View File

@ -1,6 +1,5 @@
<route lang="json5" type="page">
{
layout: 'page',
style: {
navigationStyle: 'custom',
},

View File

@ -1,6 +1,5 @@
<route lang="json5" type="page">
{
layout: 'page',
style: {
navigationStyle: 'custom',
},

View File

@ -1,6 +1,5 @@
<route lang="json5" type="page">
{
layout: 'page',
style: {
navigationStyle: 'custom',
},

View File

@ -1,41 +1,39 @@
<template>
<ActionSheet
v-model:show="localShow"
title="筛选"
@close="close"
custom-header-class="text-[36rpx]! text-[#303030]! font-medium!"
>
<view class="flex flex-col sheet-body-border">
<view class="flex">
<view class="w-[176rpx] h-initial bg-[#F7F8FA] flex flex-col items-center">
<view
:class="`flex items-center justify-center h-[104rpx] w-full ${item.id === currentMenu ? 'active' : ''}`"
v-for="item in menus"
v-for="item in splitMenus"
:key="item.id"
@click="changeMenu(item)"
>
{{ item.name }}
</view>
</view>
<view class="flex-1 pb-[24rpx] h-[50vh] overflow-y-auto">
<Phase v-show="currentMenu === 1" />
<view class="flex-1 pb-[24rpx] h-[50vh] overflow-y-auto mt-[32rpx] mx-[32rpx]">
<Phase v-show="currentMenu === 1 && showPhase" />
<Region
width="240rpx"
height="60rpx"
class="justify-center!"
v-show="currentMenu === 2"
:defaultValue="defaultRegion"
@change-name="handleRegionChange"
/>
<UniType
width="240rpx"
height="60rpx"
class="justify-center!"
v-show="currentMenu === 3"
:defaultValue="defaultUniType"
/>
<Nature
width="240rpx"
height="60rpx"
class="justify-center!"
v-show="currentMenu === 4"
:defaultValue="defaultNature"
/>
</view>
</view>
@ -61,13 +59,13 @@
</button>
<button
class="border-[#1580FF]! flex-auto bg-[#1580FF]! rounded-[8rpx]! text-[#fff]! text-[32rpx]! font-normal!"
@click="handleResult"
>
查看结果
</button>
</view>
</view>
</view>
</ActionSheet>
</template>
<script lang="ts" setup>
@ -75,20 +73,18 @@ import Phase from './Phase.vue'
import Region from './Region.vue'
import UniType from './UniType.vue'
import Nature from './Nature.vue'
import ActionSheet from '@/pages-sub/components/ActionSheet.vue'
const props = defineProps({
show: {
showPhase: {
type: Boolean,
default: false,
default: true,
},
})
const localShow = computed(() => props.show)
const emit = defineEmits(['update:show'])
const close = () => {
emit('update:show', false)
defaultRegion.value = []
defaultNature.value = []
defaultUniType.value = []
}
const menus = [
@ -97,10 +93,44 @@ const menus = [
{ id: 3, name: '院校类型' },
{ id: 4, name: '办学性质' },
]
const currentMenu = ref(1)
const splitMenus = computed(() => {
let _menus = menus
if (!props.showPhase) {
_menus = menus.filter((item) => item.id !== 1)
}
return _menus
})
const currentMenu = ref(splitMenus.value[0].id)
const changeMenu = (item: { id: number; name: string }) => {
currentMenu.value = item.id
}
const defaultRegion = ref([])
const defaultNature = ref([])
const defaultUniType = ref([])
const chooseRegion = ref([])
const chooseNature = ref([])
const chooseUniType = ref([])
const handleRegionChange = (val: string[]) => {
chooseRegion.value = val
}
const handleNatureChange = (val: string[]) => {
chooseNature.value = val
}
const handleUniTypeChange = (val: string[]) => {
chooseUniType.value = val
}
const handleResult = () => {
uni.navigateTo({
url: `/pages-sub/home/wishesList/index?province=${chooseRegion.value.join(',')}&nature=${chooseNature.value.join(',')}&uniType=${chooseUniType.value.join(',')}`,
})
}
</script>
<style lang="scss" scoped>

View File

@ -1,24 +1,28 @@
<template>
<view class="mt-[32rpx]">
<view class="">
<RadioGroup v-model="choosePhase" class="custom-radio-group">
<Radio v-for="item in phaseList" :key="item.code" :name="item.code" class="custom-radio">
{{ item.name }}
<Radio v-for="item in phaseList" :key="item.batch" :name="item.batch" class="custom-radio">
{{ item.batch }}
</Radio>
</RadioGroup>
<view
class="px-[24rpx] py-[12rpx] rounded-[8rpx] bg-[rgba(255,96,68,0.1)] flex flex-col gap-[8rpx] text-[#FF6044] text-[22rpx] w-max mx-auto mt-[82rpx]"
>
<text class="">普通类一段批次线442分线高139分</text>
<text class="">普通类二段批次线150分线高432分</text>
<text class="" v-for="item in phaseList" :key="item.batch">
{{ item.batch }}批次线{{ item.score }}线高{{ item.pressureScore }}
</text>
</view>
</view>
</template>
<script lang="ts" setup>
import { getUniversityLevel } from '@/service/index/api'
import { getBatchData, getWxUserInfo } from '@/service/index/api'
import RadioGroup from '@/pages-sub/components/radio-group/RadioGroup.vue'
import Radio from '@/pages-sub/components/radio-group/Radio.vue'
import { useUserStore } from '@/store/user'
const userStore = useUserStore()
defineOptions({
options: {
@ -28,13 +32,39 @@ defineOptions({
const phaseList = ref([])
getUniversityLevel().then((res) => {
const choosePhase = ref('')
const fetchBatchData = () => {
getBatchData(userStore.userInfo.batchDataUrl).then((res) => {
if (res.code === 200) {
phaseList.value = res.result as { code: number; name: string }[]
phaseList.value = res.result[0].batches
}
})
choosePhase.value = userStore.userInfo.batchName
}
const choosePhase = ref('')
onLoad(() => {
if (userStore.userInfo.batchDataUrl) {
fetchBatchData()
} else {
getWxUserInfo().then((resp) => {
if (resp.code === 200) {
const infoData = resp.result as unknown as {
userExtend: { provinceCode: string }
zyBatches: any[]
batchDataUrl: string
batchName: string
}
userStore.setEstimatedAchievement(infoData.userExtend)
userStore.setZyBatches(infoData.zyBatches)
userStore.setBatchDataUrl(infoData.batchDataUrl)
userStore.setBatchName(infoData.batchName)
fetchBatchData()
}
})
}
})
</script>
<style lang="scss">

View File

@ -2,7 +2,6 @@
<route lang="json5" type="page">
{
layout: 'page',
style: {
navigationStyle: 'custom',
},

View File

@ -1,6 +1,5 @@
<route lang="json5" type="page">
{
layout: 'page',
style: {
navigationStyle: 'custom',
},

View File

@ -1,6 +1,5 @@
<route lang="json5" type="page">
{
layout: 'page',
style: {
navigationStyle: 'custom',
},
@ -129,6 +128,8 @@ import {
optionalSubjectList,
} from '@/pages-sub/home/inputScore/useRules'
import { savePerfectInfo } from '@/service/index/api'
const userStore = useUserStore()
const show = ref(false)
@ -155,12 +156,10 @@ const handleChange = (e: any) => {
}
//
const requireSubject = ref(userStore.userInfo.estimatedAchievement.requireSubject.code || '')
const requireSubject = ref<number | string>('')
//
const optionalSubject = ref(
userStore.userInfo.estimatedAchievement.optionalSubject.map((item) => item.code),
)
const optionalSubject = ref<any[]>([])
//
const btnFlag = computed(() => {
@ -172,7 +171,13 @@ const btnFlag = computed(() => {
return num
})
onBeforeMount(() => {
onLoad(() => {
userStore.$subscribe((mutation, state) => {
requireSubject.value = userStore.userInfo.estimatedAchievement.requireSubject.code || ''
optionalSubject.value = userStore.userInfo.estimatedAchievement.optionalSubject.map(
(item) => item.code,
)
})
useRules()
})
@ -184,8 +189,8 @@ const saveScore = () => {
return
}
const data = {
year: term, //
score: score.value, //
year: term.value, //
expectedScore: score.value, //
optionalSubject: optionalSubjectList.value.filter((item) =>
optionalSubject.value.includes(item.code),
), //
@ -193,16 +198,38 @@ const saveScore = () => {
cityCode: userStore.userInfo.city.code, // code
}
userStore.setEstimatedAchievement(data)
const subjects = data.optionalSubject
.map((item) => item.simplename)
.concat(data.requireSubject ? data.requireSubject : [])
.join(',')
userStore.setEstimatedAchievement({ ...data, subjectGroup: subjects })
savePerfectInfo({
year: term.value,
score: Number(score.value),
subjectGroup: subjects,
provinceCode: userStore.userInfo.estimatedAchievement.provinceCode,
provinceName: userStore.userInfo.estimatedAchievement.provinceName,
}).then((res) => {
if (res.code === 200) {
uni.showToast({
title: '保存成功',
icon: 'none',
})
setTimeout(() => {
uni.navigateBack()
uni.navigateBack({
fail: () => {
//
uni.switchTab({
url: '/pages/home/index/index',
})
},
})
}, 500)
}
})
}
</script>
<style lang="scss" scoped>

View File

@ -21,6 +21,22 @@ export const useRules = () => {
const matchRules = matchRule.length > 0 ? matchRule[0].rule : []
requireSubjectList.value = matchRules.filter((item) => item?.isfirst === 'true')
optionalSubjectList.value = matchRules.filter((item) => !(item?.isfirst === 'true'))
splitSubject(requireSubjectList.value, optionalSubjectList.value)
}
})
}
// 分离学科,然后将学科分类存储到用户的期望数据上
const splitSubject = (requireSubjectList: any[], optionalSubjectList: any[]) => {
const subjectGroup = userStore.userInfo.estimatedAchievement.subjectGroup
const splitRule = subjectGroup.split(',')
const requireSubject = requireSubjectList.filter((item) => splitRule.includes(item.simplename))
const optionalSubject = optionalSubjectList.filter((item) => splitRule.includes(item.simplename))
userStore.setEstimatedAchievement({
requireSubject,
optionalSubject,
})
}

View File

@ -1,6 +1,5 @@
<route lang="json5" type="page">
{
layout: 'page',
style: {
navigationStyle: 'custom',
},

View File

@ -1,6 +1,5 @@
<route lang="json5" type="page">
{
layout: 'page',
style: {
navigationStyle: 'custom',
},

View File

@ -1,6 +1,5 @@
<route lang="json5" type="page">
{
layout: 'page',
style: {
navigationStyle: 'custom',
},

View File

@ -1,6 +1,5 @@
<route lang="json5" type="page">
{
layout: 'page',
style: {
navigationStyle: 'custom',
},

View File

@ -1,6 +1,5 @@
<route lang="json5" type="page">
{
layout: 'page',
style: {
navigationStyle: 'custom',
},

View File

@ -1,6 +1,5 @@
<route lang="json5" type="page">
{
layout: 'page',
style: {
navigationStyle: 'custom',
},

View File

@ -0,0 +1,180 @@
<route lang="json5" type="page">
{
style: {
navigationBarTitleText: '我的志愿表',
},
}
</route>
<template>
<z-paging
ref="paging"
use-virtual-list
:force-close-inner-list="true"
cell-height-mode="dynamic"
@virtualListChange="virtualListChange"
@query="queryList"
:auto-show-system-loading="true"
>
<template #top>
<view
class="bg-[#E2EDF9] text-[#1580FF] text-[22rpx] flex justify-between items-center px-[32rpx] py-[10rpx]"
>
<view class="flex gap-[16rpx]">
<text>{{ userStore.userInfo.estimatedAchievement.expectedScore }}</text>
<text>
{{ userStore.userInfo.estimatedAchievement.subjectGroup.split(',').join('/') }}
</text>
<text>{{ userStore.userInfo.batchName }}</text>
</view>
<view>
<text>重要提示</text>
<text class="i-carbon-help"></text>
</view>
</view>
<view class="flex justify-between items-center px-[32rpx] py-[16rpx]">
<view class="flex items-center gap-[24rpx] text-[#303030]">
<view
@click="handleShow(1)"
class="flex justify-between items-center text-[28rpx] line-height-none"
>
院校
<view class="i-carbon-caret-down"></view>
</view>
<view
@click="handleShow(2)"
class="flex justify-between items-center text-[28rpx] line-height-none ml-[20rpx]"
>
地域
<view class="i-carbon-caret-down"></view>
</view>
</view>
<SearchInput
v-model:value="searchValue"
@confirm="handleChange"
placeholder="请输入意向院校"
/>
</view>
<view class="flex gap-[10rpx] px-[32rpx] border-top">
<view
@click="handleShow(3)"
class="flex justify-between items-center text-[28rpx] line-height-none"
>
全部(15)
<view class="i-carbon-caret-down"></view>
</view>
<Slider
v-model:modelValue="sliderValue"
:min="500"
:max="600"
:step="1"
:range="true"
@change="handleSliderChange"
class="custom-slider"
/>
</view>
<view class="h-[16rpx] bg-[#F5F5F5]"></view>
</template>
<!-- 滚动主体 -->
<view
class="item-wrapper"
:id="`zp-id-${item.zp_index}`"
:key="item.zp_index"
v-for="(item, index) in schoolList"
@click="itemClick(item, item.zp_index)"
></view>
<ActionSheet v-model:show="show" :title="actionTitle">
<view class="py-[16rpx]">
<Region
v-if="actionTitle === '地域'"
width="210rpx"
height="60rpx"
class="px-[32rpx]"
@change-name="handleRegionName"
/>
<FilterMenu v-if="actionTitle === ''" :show-phase="false" />
</view>
<view class="flex items-center justify-between px-[32rpx]" v-show="actionTitle === '地域'">
<view class="cancel-btn" @click="show = false">取消</view>
<view class="submit-btn" @click="handleConfirm"></view>
</view>
</ActionSheet>
</z-paging>
</template>
<script lang="ts" setup>
import SearchInput from '@/pages-sub/components/input/SearchInput.vue'
import ActionSheet from '@/pages-sub/components/ActionSheet.vue'
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 { useUserStore } from '@/store/user'
const userStore = useUserStore()
const sliderValue = ref([550, 590])
const schoolList = ref([])
const paging = ref(null)
const queryList = (page: number, pageSize: number) => {
paging.value.complete([])
}
const virtualListChange = (_vList) => {
schoolList.value = _vList
}
const itemClick = (item, index) => {
uni.navigateTo({ url: `/pages-sub/home/college/info?collegeId=${item._id}` })
}
const collegeSearch = ref({
nature: '',
feature: '',
majors: '',
})
const show = ref(false)
const actionTitle = ref('')
const handleConfirm = () => {
show.value = false
}
const handleShow = (type: number) => {
actionTitle.value = type === 1 ? '院校' : '地域'
show.value = true
}
const searchValue = ref('')
const handleChange = () => {
console.log(searchValue.value)
}
const handleRegionName = (val: string[]) => {
console.log(val)
}
const handleSliderChange = (val) => {
console.log('滑块值变化:', val)
}
</script>
<style lang="scss" scoped>
@import '@/pages-sub/home/styles/picker-view-btn.scss';
.custom-slider {
flex: 1 1 auto;
}
.border-top {
border-top: 2rpx solid #ededed;
}
</style>

View File

@ -73,7 +73,6 @@
{
"path": "pages/expert/index/index",
"type": "page",
"layout": "page",
"style": {
"navigationBarTitleText": "测评师"
},
@ -115,7 +114,6 @@
{
"path": "customerService/index/index",
"type": "page",
"layout": "page",
"style": {
"navigationStyle": "custom"
}
@ -123,7 +121,6 @@
{
"path": "home/aiAutoFill/index",
"type": "page",
"layout": "page",
"style": {
"navigationStyle": "custom"
}
@ -131,7 +128,6 @@
{
"path": "home/autoFill/index",
"type": "page",
"layout": "page",
"style": {
"navigationStyle": "custom"
},
@ -140,7 +136,6 @@
{
"path": "home/career/index",
"type": "page",
"layout": "page",
"style": {
"navigationStyle": "custom"
},
@ -149,7 +144,6 @@
{
"path": "home/career/info",
"type": "page",
"layout": "page",
"style": {
"navigationStyle": "custom"
}
@ -157,7 +151,6 @@
{
"path": "home/city/index",
"type": "page",
"layout": "page",
"style": {
"navigationStyle": "custom"
}
@ -165,7 +158,6 @@
{
"path": "home/college/enrollmentIntroDetail",
"type": "page",
"layout": "page",
"style": {
"navigationStyle": "custom"
}
@ -181,7 +173,6 @@
{
"path": "home/college/info",
"type": "page",
"layout": "page",
"style": {
"navigationStyle": "custom"
}
@ -189,7 +180,6 @@
{
"path": "home/distinguish/index",
"type": "page",
"layout": "page",
"style": {
"navigationStyle": "custom"
}
@ -201,7 +191,6 @@
{
"path": "home/expand/index",
"type": "page",
"layout": "page",
"style": {
"navigationStyle": "custom"
}
@ -209,7 +198,6 @@
{
"path": "home/inputScore/index",
"type": "page",
"layout": "page",
"style": {
"navigationStyle": "custom"
},
@ -218,7 +206,6 @@
{
"path": "home/line/index",
"type": "page",
"layout": "page",
"style": {
"navigationStyle": "custom"
}
@ -226,7 +213,6 @@
{
"path": "home/major/index",
"type": "page",
"layout": "page",
"style": {
"navigationStyle": "custom"
},
@ -235,7 +221,6 @@
{
"path": "home/major/info",
"type": "page",
"layout": "page",
"style": {
"navigationStyle": "custom"
}
@ -243,7 +228,6 @@
{
"path": "home/news/index",
"type": "page",
"layout": "page",
"style": {
"navigationStyle": "custom"
}
@ -251,7 +235,6 @@
{
"path": "home/news/newsList",
"type": "page",
"layout": "page",
"style": {
"navigationStyle": "custom"
}
@ -259,10 +242,16 @@
{
"path": "home/schoolRank/index",
"type": "page",
"layout": "page",
"style": {
"navigationStyle": "custom"
}
},
{
"path": "home/wishesList/index",
"type": "page",
"style": {
"navigationBarTitleText": "我的志愿表"
}
}
]
},
@ -289,7 +278,6 @@
{
"path": "rank/index",
"type": "page",
"layout": "page",
"style": {
"navigationStyle": "custom"
}

View File

@ -1,6 +1,5 @@
<route lang="json5" type="page">
{
layout: 'page',
style: {
navigationBarTitleText: '测评师',
},

View File

@ -201,3 +201,38 @@ export const getUserCity = (params: { lat: number; lng: number }) => {
...params,
})
}
export const savePerfectInfo = (params: {
provinceCode?: string
provinceName?: string
schoolName?: string
className?: string
subjectGroup?: string
score?: number
sp?: number
year?: number
}) => {
return http.post('/api/weChatUserEx/perfectInfo', params)
}
export const getBatchData = (url: string) => {
return http.get(url, { haPrefix: true })
}
export interface filterParams {
batchName?: null | string
feature?: string[] | null
keyword?: null | string
locationCode?: null | string
majors?: string[] | null
nature?: string[] | null
ownership?: string[] | null
pageIndex?: number
pageSize?: number
province?: string[] | null
subjects?: string[] | null
universityName?: null | string
}
export const getFilterData = (params: filterParams) => {
return http.get('/api/PlanPro/planList', params)
}

View File

@ -49,6 +49,13 @@ const initState = {
},
token: '',
openid: '',
zyBatches: {
batchName: '',
count: 0,
itemCount: 0,
},
batchDataUrl: '',
batchName: '',
}
export const useUserStore = defineStore(
@ -99,6 +106,17 @@ export const useUserStore = defineStore(
})
}
const setZyBatches = (val: any) => {
userInfo.value.zyBatches = val
}
const setBatchDataUrl = (val: string) => {
userInfo.value.batchDataUrl = val
}
const setBatchName = (val: string) => {
userInfo.value.batchName = val
}
// 清除用户信息
const clearUserInfo = () => {
userInfo.value = { ...initState }
@ -122,6 +140,9 @@ export const useUserStore = defineStore(
setUserOpenId,
setUserNickName,
setUserAvatar,
setZyBatches,
setBatchDataUrl,
setBatchName,
}
},
{

View File

@ -55,6 +55,13 @@ export type ExtraUserInfo = {
vipCode: string | null
wxId: number
}
zyBatches: {
batchName: string
count: number
itemCount: number
}
batchDataUrl: string
batchName: string
} & IUserInfo
export type News = {

View File

@ -28,6 +28,7 @@ interface NavigateToOptions {
"/pages-sub/home/news/index" |
"/pages-sub/home/news/newsList" |
"/pages-sub/home/schoolRank/index" |
"/pages-sub/home/wishesList/index" |
"/login-sub/index" |
"/pages-evaluation-sub/index" |
"/pages-evaluation-sub/rank/index";