feat: 分数线页面

master
xjs 2025-03-10 18:04:51 +08:00
parent 8d0e7ebcd0
commit be40ec0395
42 changed files with 1766 additions and 287 deletions

View File

@ -66,11 +66,11 @@ importers:
specifier: 1.11.10
version: 1.11.10
pinia:
specifier: 2.0.36
version: 2.0.36(typescript@5.7.2)(vue@3.4.21(typescript@5.7.2))
specifier: ^3.0.1
version: 3.0.1(typescript@5.7.2)(vue@3.4.21(typescript@5.7.2))
pinia-plugin-persistedstate:
specifier: 3.2.1
version: 3.2.1(pinia@2.0.36(typescript@5.7.2)(vue@3.4.21(typescript@5.7.2)))
version: 3.2.1(pinia@3.0.1(typescript@5.7.2)(vue@3.4.21(typescript@5.7.2)))
pinyin-pro:
specifier: ^3.26.0
version: 3.26.0
@ -2109,6 +2109,15 @@ packages:
'@vue/devtools-api@6.6.4':
resolution: {integrity: sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==}
'@vue/devtools-api@7.7.2':
resolution: {integrity: sha512-1syn558KhyN+chO5SjlZIwJ8bV/bQ1nOVTG66t2RbG66ZGekyiYNmRO7X9BJCXQqPsFHlnksqvPhce2qpzxFnA==}
'@vue/devtools-kit@7.7.2':
resolution: {integrity: sha512-CY0I1JH3Z8PECbn6k3TqM1Bk9ASWxeMtTCvZr7vb+CHi+X/QwQm5F1/fPagraamKMAHVfuuCbdcnNg1A4CYVWQ==}
'@vue/devtools-shared@7.7.2':
resolution: {integrity: sha512-uBFxnp8gwW2vD6FrJB8JZLUzVb6PNRG0B0jBnHsOH8uKyva2qINY8PTF5Te4QlTbMDqU5K6qtJDr6cNsKWhbOA==}
'@vue/language-core@1.8.27':
resolution: {integrity: sha512-L8Kc27VdQserNaCUNiSFdDl9LWT24ly8Hpwf1ECy3aFb9m6bDhBGQYOujDm21N7EW3moKIOKEanQwe1q5BK+mA==}
peerDependencies:
@ -2424,6 +2433,9 @@ packages:
bing-translate-api@4.0.2:
resolution: {integrity: sha512-JJ8XUehnxzOhHU91oy86xEtp8OOMjVEjCZJX042fKxoO19NNvxJ5omeCcxQNFoPbDqVpBJwqiGVquL0oPdQm1Q==}
birpc@0.2.19:
resolution: {integrity: sha512-5WeXXAvTmitV1RqJFppT5QtUiz2p1mRSYU000Jkft5ZUCLJIk4uQriYNO50HknxKwM6jd8utNc66K1qGIwwWBQ==}
bluebird@3.7.2:
resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==}
@ -2719,6 +2731,10 @@ packages:
resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==}
engines: {node: '>= 0.6'}
copy-anything@3.0.5:
resolution: {integrity: sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==}
engines: {node: '>=12.13'}
copy-descriptor@0.1.1:
resolution: {integrity: sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==}
engines: {node: '>=0.10.0'}
@ -3768,6 +3784,9 @@ packages:
resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
hasBin: true
hookable@5.5.3:
resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==}
hosted-git-info@2.8.9:
resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==}
@ -4155,6 +4174,10 @@ packages:
resolution: {integrity: sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==}
engines: {node: '>= 0.4'}
is-what@4.1.16:
resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==}
engines: {node: '>=12.13'}
is-windows@1.0.2:
resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==}
engines: {node: '>=0.10.0'}
@ -4774,6 +4797,9 @@ packages:
mitt@1.1.2:
resolution: {integrity: sha512-3btxP0O9iGADGWAkteQ8mzDtEspZqu4I32y4GZYCV5BrwtzdcRpF4dQgNdJadCrbBx7Lu6Sq9AVrerMHR0Hkmw==}
mitt@3.0.1:
resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==}
mixin-deep@1.3.2:
resolution: {integrity: sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==}
engines: {node: '>=0.10.0'}
@ -5150,15 +5176,12 @@ packages:
peerDependencies:
pinia: ^2.0.0
pinia@2.0.36:
resolution: {integrity: sha512-4UKApwjlmJH+VuHKgA+zQMddcCb3ezYnyewQ9NVrsDqZ/j9dMv5+rh+1r48whKNdpFkZAWVxhBp5ewYaYX9JcQ==}
pinia@3.0.1:
resolution: {integrity: sha512-WXglsDzztOTH6IfcJ99ltYZin2mY8XZCXujkYWVIJlBjqsP6ST7zw+Aarh63E1cDVYeyUcPCxPHzJpEOmzB6Wg==}
peerDependencies:
'@vue/composition-api': ^1.4.0
typescript: '>=4.4.4'
vue: ^2.6.14 || ^3.2.0
vue: ^2.7.0 || ^3.5.11
peerDependenciesMeta:
'@vue/composition-api':
optional: true
typescript:
optional: true
@ -5795,6 +5818,10 @@ packages:
spdx-license-ids@3.0.20:
resolution: {integrity: sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==}
speakingurl@14.0.1:
resolution: {integrity: sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==}
engines: {node: '>=0.10.0'}
split-string@3.1.0:
resolution: {integrity: sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==}
engines: {node: '>=0.10.0'}
@ -5973,6 +6000,10 @@ packages:
engines: {node: '>=18.12.0'}
hasBin: true
superjson@2.2.2:
resolution: {integrity: sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q==}
engines: {node: '>=16'}
supports-color@2.0.0:
resolution: {integrity: sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==}
engines: {node: '>=0.8.0'}
@ -9500,6 +9531,24 @@ snapshots:
'@vue/devtools-api@6.6.4': {}
'@vue/devtools-api@7.7.2':
dependencies:
'@vue/devtools-kit': 7.7.2
'@vue/devtools-kit@7.7.2':
dependencies:
'@vue/devtools-shared': 7.7.2
birpc: 0.2.19
hookable: 5.5.3
mitt: 3.0.1
perfect-debounce: 1.0.0
speakingurl: 14.0.1
superjson: 2.2.2
'@vue/devtools-shared@7.7.2':
dependencies:
rfdc: 1.4.1
'@vue/language-core@1.8.27(typescript@5.7.2)':
dependencies:
'@volar/language-core': 1.11.1
@ -9869,6 +9918,8 @@ snapshots:
dependencies:
got: 11.8.6
birpc@0.2.19: {}
bluebird@3.7.2: {}
bmp-js@0.1.0: {}
@ -10201,6 +10252,10 @@ snapshots:
cookie@0.7.1: {}
copy-anything@3.0.5:
dependencies:
is-what: 4.1.16
copy-descriptor@0.1.1: {}
core-js-compat@3.39.0:
@ -11473,6 +11528,8 @@ snapshots:
he@1.2.0: {}
hookable@5.5.3: {}
hosted-git-info@2.8.9: {}
hosted-git-info@4.1.0:
@ -11837,6 +11894,8 @@ snapshots:
call-bind: 1.0.7
get-intrinsic: 1.2.4
is-what@4.1.16: {}
is-windows@1.0.2: {}
is-wsl@2.2.0:
@ -12673,6 +12732,8 @@ snapshots:
mitt@1.1.2: {}
mitt@3.0.1: {}
mixin-deep@1.3.2:
dependencies:
for-in: 1.0.2
@ -13080,15 +13141,14 @@ snapshots:
pify@2.3.0: {}
pinia-plugin-persistedstate@3.2.1(pinia@2.0.36(typescript@5.7.2)(vue@3.4.21(typescript@5.7.2))):
pinia-plugin-persistedstate@3.2.1(pinia@3.0.1(typescript@5.7.2)(vue@3.4.21(typescript@5.7.2))):
dependencies:
pinia: 2.0.36(typescript@5.7.2)(vue@3.4.21(typescript@5.7.2))
pinia: 3.0.1(typescript@5.7.2)(vue@3.4.21(typescript@5.7.2))
pinia@2.0.36(typescript@5.7.2)(vue@3.4.21(typescript@5.7.2)):
pinia@3.0.1(typescript@5.7.2)(vue@3.4.21(typescript@5.7.2)):
dependencies:
'@vue/devtools-api': 6.6.4
'@vue/devtools-api': 7.7.2
vue: 3.4.21(typescript@5.7.2)
vue-demi: 0.14.10(vue@3.4.21(typescript@5.7.2))
optionalDependencies:
typescript: 5.7.2
@ -13798,6 +13858,8 @@ snapshots:
spdx-license-ids@3.0.20: {}
speakingurl@14.0.1: {}
split-string@3.1.0:
dependencies:
extend-shallow: 3.0.2
@ -14023,6 +14085,10 @@ snapshots:
- supports-color
- typescript
superjson@2.2.2:
dependencies:
copy-anything: 3.0.5
supports-color@2.0.0: {}
supports-color@3.2.3:

View File

@ -9,20 +9,18 @@
<image class="w-[42rpx] h-[39rpx]" src="/static/images/home/pen.svg"></image>
</view>
<view class="mt-[56rpx] flex items-center justify-between">
<wd-button
custom-class="w-[240rpx]! h-[88rpx]! border-[#1580FF]! text-[#1580FF]! text-[28rpx]! font-normal! mr-[32rpx]"
:round="false"
<button
class="w-[240rpx]! h-[88rpx]! border-[#1580FF]! text-[#1580FF]! text-[28rpx]! font-normal! mr-[32rpx] flex! items-center! justify-center! rounded-[8rpx]!"
plain
@click="navigatorTo"
>
一键填报
</wd-button>
<wd-button
:round="false"
custom-class="w-[350rpx]! h-[88rpx]! text-[#fff]! text-[28rpx]! bg-[#1580FF]! font-normal"
</button>
<button
class="w-[350rpx]! h-[88rpx]! text-[#fff]! text-[28rpx]! bg-[#1580FF]! font-normal flex! items-center! justify-center! rounded-[8rpx]!"
>
智能填报
</wd-button>
</button>
</view>
</view>
</template>

View File

@ -0,0 +1,205 @@
<template>
<view class="navbar">
<!-- 状态栏占位 -->
<view
v-if="safeAreaInsetTop"
class="status-bar"
:style="{ height: statusBarHeight + 'px', backgroundColor: bgColor }"
></view>
<!-- 导航栏主体 -->
<view
class="navbar-content"
:class="[contentClass, fixed ? 'navbar-fixed' : '', bordered ? 'navbar-border' : '']"
:style="{
backgroundColor: bgColor,
height: navHeight + 'px',
top: fixed ? (safeAreaInsetTop ? statusBarHeight : 0) + 'px' : '0',
}"
>
<!-- 左侧区域 -->
<view class="navbar-left" @click="handleClickLeft">
<view v-if="leftArrow" class="back-icon">
<view class="i-carbon-chevron-left text-[48rpx] text-[#333] font-semibold" />
</view>
<slot name="left"></slot>
</view>
<!-- 中间标题区域 -->
<view class="navbar-title">
<slot name="title">
<text class="title-text">{{ title }}</text>
</slot>
</view>
<!-- 右侧区域 -->
<view class="navbar-right">
<slot name="right"></slot>
</view>
</view>
<!-- 占位元素 -->
<view
v-if="placeholder && fixed"
:style="{
height: `${navHeight}px`,
backgroundColor: bgColor,
}"
></view>
<slot name="background"></slot>
</view>
</template>
<script lang="ts" setup>
import { computed } from 'vue'
const props = defineProps({
title: {
type: String,
default: '',
},
leftArrow: {
type: Boolean,
default: false,
},
fixed: {
type: Boolean,
default: false,
},
placeholder: {
type: Boolean,
default: false,
},
bordered: {
type: Boolean,
default: true,
},
safeAreaInsetTop: {
type: Boolean,
default: true,
},
bgColor: {
type: String,
default: '#ffffff',
},
contentClass: {
type: String,
default: 'justify-between',
},
})
const emit = defineEmits(['clickLeft'])
//
const systemInfo = uni.getSystemInfoSync()
const statusBarHeight = systemInfo.statusBarHeight || 0
//
const navHeight = computed(() => {
//
const { platform, screenWidth } = systemInfo
// pxrpx
const ratio = 750 / screenWidth
//
if (platform === 'ios') {
return 88 / ratio // iOS 44ptpx
} else if (platform === 'android') {
return 96 / ratio // Android 48dppx
} else {
return 88 / ratio //
}
})
const handleClickLeft = () => {
emit('clickLeft')
}
</script>
<style scoped>
.navbar {
width: 100%;
}
.status-bar {
width: 100%;
background-color: inherit;
}
.navbar-content {
width: 100%;
display: flex;
align-items: center;
/* justify-content: space-between; */
padding: 0 32rpx;
box-sizing: border-box;
background-color: #fff;
}
.navbar-fixed {
position: fixed;
left: 0;
width: 100%;
z-index: 99;
}
.navbar-border {
border-bottom: 1rpx solid #eee;
}
.navbar-left {
display: flex;
align-items: center;
height: 100%;
}
.back-icon {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
}
.navbar-title {
/* flex: 1; */
text-align: center;
overflow: hidden;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.title-text {
font-size: 36rpx;
color: #333;
font-weight: 500;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.navbar-right {
display: flex;
align-items: center;
min-width: 100rpx;
justify-content: flex-end;
height: 100%;
}
@font-face {
font-family: 'iconfont';
src: url('data:font/woff2;charset=utf-8;base64,d09GMgABAAAAAAKYAAsAAAAABlAAAAJMAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHFQGYACCcApcdgE2AiQDCAsGAAQgBYRnBzYbmQXIHpIkBQQKkYCABBEPz2/t/XN3twEbowBkQTxQEQ1RKaKSxEOi0agkJKF5Qvj/f037IFKwlZ2dWU2tJu0EhPwHkBwgOVAclKcvAQpI/v/fz/08XECy+YBymmPQiwIcSmhAY4uSFcgJ+IaxC1zCYwLtRjWSnZ2rGgQWBowLxCPrVBBYllQqNTQ0VISaBXEHtTRNUwW4jb4f/xYEC0kqMzDx6CGrQuKXxKc6Zf7POYQgQHs5kIwjYwEoxK3G/DpRwbi0dlNwKKjAL4lf6vw/R2zVWvTPIwuiCnp2wCRUZ3yJX5pJFVDfByyAFR2AblMAX/OR3t7+zOJi8GyyfzC1uQXLZvtnk/0zyfTy+PvH0/Xp5OzR98/H797/+/fDu3d/3739+/fd+/+nmxvLc5vrS+sry2vz84tLs9Mzc4vzs9NTM/Ozc1OzM3MzU/Mz0wvTU4vTk0tTE8uTEyuT4yv/G0E3XUxv7wwNbu/s9G8fbO9v7+3sb+3ubW4dbO4dbO3vbu4dbO3JzqPFtRE4gEGAX0NBkL+hpCZALkEp5FKUQqE0NHlXJIGrDNAOcEQBCHU+kXT5QNblC7kEv1EK9Y9SB/8o7YYu2m0YXrJLouNIjQJhH+QbVkVZrUQ+YuqzUJdzxPMHhdIj0+hg4o0D8ogj5r5bSoQUxjADz+A8hBDQFEYwh3mommXTul7Vm5ZtqAqJHIdoKCDYDyQ3mCqUG1YKn5+C0s0yiJ/qKVAQedKAhg6Y3mEHJBQaWKnvLVMiiEIxGAY8Aw6HIAhAJmEIzIIOUjLTTAB1taL1QvNq+fYN7QDjcc2okeioaOmy5LFXt3QAAAAA')
format('woff2');
}
.back-text {
font-family: 'iconfont' !important;
font-size: 48rpx;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: #333;
}
</style>

View File

@ -24,10 +24,10 @@
手机号快捷登录
</button>
<view class="flex items-center flex-nowrap" @click.stop="checked = true">
<wd-radio-group v-model="checked" custom-class="mr-10rpx">
<wd-radio :value="true" shape="dot"></wd-radio>
</wd-radio-group>
<view class="flex items-center flex-nowrap" @click.stop="checked = 1">
<RadioGroup v-model="checked" custom-class="mr-10rpx">
<Radio :name="1"></Radio>
</RadioGroup>
<view class="flex items-center">
<text class="text-[24rpx] whitespace-nowrap">
已阅读并同意服务条款隐私条款
@ -42,6 +42,8 @@
<script lang="ts" setup>
import { useLogin } from '@/login-sub/hooks/useUserInfo'
import Overlay from './Overlay.vue'
import RadioGroup from './radio-group/RadioGroup.vue'
import Radio from './radio-group/Radio.vue'
import {
getSessionKey,
getVolunteerInitialization,
@ -72,7 +74,7 @@ const handleClose = () => {
}
const phone = ref(true) //
const checked = ref(false) //
const checked = ref(0) //
const getPhoneInfo = ref(null)
const getPhoneNumber = async (e: any) => {

View File

@ -0,0 +1,113 @@
<template>
<view
class="radio"
:class="{
'radio--disabled': isDisabled,
'radio-active': isChecked,
}"
@click="handleClick"
>
<view class="radio__icon" :class="{ 'radio__icon--checked': isChecked }">
<view v-if="isChecked" class="radio__icon-dot"></view>
</view>
<view class="radio__label">
<slot>{{ label }}</slot>
</view>
</view>
</template>
<script lang="ts" setup>
import { computed, inject } from 'vue'
const props = defineProps({
name: {
type: [String, Number],
required: true,
},
label: {
type: String,
default: '',
},
disabled: {
type: Boolean,
default: false,
},
})
interface RadioGroupContext {
modelValue: ComputedRef<string | number>
disabled: ComputedRef<boolean>
toggleOption: (value: string | number) => void
}
// radio group
const radioGroup = inject<RadioGroupContext>('radioGroup', {
modelValue: computed(() => ''),
disabled: computed(() => false),
toggleOption: () => {},
})
//
const isChecked = computed(() => {
return radioGroup.modelValue.value === props.name
})
//
const isDisabled = computed(() => {
return props.disabled || radioGroup.disabled.value
})
//
const handleClick = () => {
if (isDisabled.value) return
radioGroup.toggleOption(props.name)
}
</script>
<style scoped lang="scss">
.radio {
display: inline-flex;
align-items: center;
cursor: pointer;
font-size: 28rpx;
width: 100%;
height: 100%;
justify-content: center;
&--disabled {
cursor: not-allowed;
opacity: 0.5;
}
&__icon {
width: 40rpx;
height: 40rpx;
border: 2rpx solid #dcdfe6;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin-right: 8rpx;
transition: all 0.2s;
&--checked {
border-color: #0083ff;
}
}
&__icon-dot {
width: 20rpx;
height: 20rpx;
background-color: #0083ff;
border-radius: 50%;
}
&__label {
line-height: 1;
}
}
.radio-active {
color: #0083ff;
}
</style>

View File

@ -0,0 +1,43 @@
<template>
<view class="radio-group">
<slot></slot>
</view>
</template>
<script lang="ts" setup>
import { provide, computed } from 'vue'
const props = defineProps({
modelValue: {
type: [String, Number],
default: '',
},
disabled: {
type: Boolean,
default: false,
},
})
const emit = defineEmits(['update:modelValue', 'change'])
//
const toggleOption = (value: string | number) => {
emit('update:modelValue', value)
emit('change', value)
}
// radio
provide('radioGroup', {
modelValue: computed(() => props.modelValue),
disabled: computed(() => props.disabled),
toggleOption,
})
</script>
<style scoped lang="scss">
.radio-group {
display: flex;
flex-wrap: wrap;
gap: 20rpx;
}
</style>

View File

@ -0,0 +1,121 @@
<template>
<view class="badge">
<slot></slot>
<view
v-show="showBadge"
class="badge__content"
:class="{
'badge__content--dot': isDot,
'badge__content--fixed': !$slots.default,
}"
:style="badgeStyle"
>
<block v-if="!isDot">{{ finalContent }}</block>
</view>
</view>
</template>
<script lang="ts" setup>
import { computed } from 'vue'
const props = defineProps({
value: {
type: [String, Number],
default: '',
},
max: {
type: Number,
default: 99,
},
isDot: {
type: Boolean,
default: false,
},
hidden: {
type: Boolean,
default: false,
},
bgColor: {
type: String,
default: '#ff4d4f',
},
color: {
type: String,
default: '#fff',
},
})
//
const showBadge = computed(() => {
return !props.hidden && (props.isDot || content.value)
})
//
const content = computed(() => {
return props.value !== '' && props.value !== undefined && props.value !== null
})
//
const finalContent = computed(() => {
if (!content.value) return ''
if (typeof props.value === 'number' || !isNaN(Number(props.value))) {
const value = Number(props.value)
const result = value > props.max ? `${props.max}+` : value
return result
}
return String(props.value)
})
//
const badgeStyle = computed(() => {
const style: Record<string, string> = {
backgroundColor: props.bgColor,
color: props.color,
}
return style
})
</script>
<style lang="scss" scoped>
.badge {
position: relative;
display: inline-flex;
vertical-align: middle;
&__content {
position: absolute;
top: 8rpx;
right: 8rpx;
transform: translate(50%, -50%);
transform-origin: 100% 0%;
z-index: 10;
min-width: 32rpx;
height: 32rpx;
padding: 0 8rpx;
color: #fff;
font-size: 20rpx;
line-height: 32rpx;
white-space: nowrap;
text-align: center;
background-color: #ff4d4f;
border-radius: 16rpx;
box-shadow: 0 0 0 2rpx #fff;
&--dot {
width: 16rpx;
height: 16rpx;
padding: 0;
min-width: auto;
border-radius: 50%;
}
&--fixed {
position: relative;
transform: none;
}
}
}
</style>

View File

@ -0,0 +1,96 @@
<template>
<CheckboxGroup v-model="defValue" checked-color="#1580FF" @change="handleChange" v-bind="$attrs">
<Checkbox
v-for="item in list"
:key="item[valueKey]"
:name="item[valueKey]"
cell
shape="button"
class="custom-checkbox"
custom-label-class="min-w-[152rpx]! h-[76rpx]! rounded-[8rpx]! checkbox-item-border bg-[#f7f8fa]!"
>
{{ item[labelKey] }}
</Checkbox>
</CheckboxGroup>
</template>
<script lang="ts" setup>
import Checkbox from './Checkbox.vue'
import CheckboxGroup from './CheckboxGroup.vue'
const props = defineProps({
list: {
type: Array,
default: () => [],
},
labelKey: {
type: String,
default: 'name',
},
valueKey: {
type: String,
default: 'code',
},
defaultValue: {
type: Array<string>,
default: () => [],
},
})
defineOptions({
options: {
styleIsolation: 'shared',
},
})
const emits = defineEmits(['change'])
const defValue = ref<string[]>([])
//
onMounted(() => {
if (props.defaultValue?.length) {
defValue.value = [...props.defaultValue]
}
})
const handleChange = (val: unknown) => {
defValue.value = val as string[]
emits('change', val)
}
watch(
() => props.defaultValue,
(newVal) => {
defValue.value = [...newVal]
},
)
</script>
<style lang="scss" scoped>
:deep(.custom-checkbox) {
.checkbox {
width: 216rpx;
height: 60rpx;
background-color: #f7f8fa;
border-radius: 8rpx;
display: flex;
align-items: center;
justify-content: center;
border: 2rpx solid #f7f8fa;
}
.checkbox__icon {
display: none;
}
}
:deep(.checkbox-group) {
display: flex;
flex-wrap: wrap;
gap: 16rpx;
padding: 32rpx 16rpx 16rpx;
}
:deep(.checkbox-active) {
border-color: #1580ff !important;
.checkbox__label {
color: #1580ff !important;
}
}
</style>

View File

@ -0,0 +1,133 @@
<template>
<view
class="checkbox"
:class="{
'checkbox--disabled': isDisabled,
'checkbox-active': isChecked,
'checkbox-disabled': isDisabled,
}"
@click="handleClick"
>
<view class="checkbox__icon" :class="{ 'checkbox__icon--checked': isChecked }">
<text v-if="isChecked" class="i-carbon-checkmark checkbox__icon-check"></text>
</view>
<view class="checkbox__label">
<slot>{{ label }}</slot>
</view>
</view>
</template>
<script lang="ts" setup>
import { computed, inject } from 'vue'
const props = defineProps({
name: {
type: [String, Number],
required: true,
},
label: {
type: String,
default: '',
},
disabled: {
type: Boolean,
default: false,
},
})
const emit = defineEmits(['change'])
interface CheckboxGroupContext {
modelValue: ComputedRef<any[]>
disabled: ComputedRef<boolean>
max: ComputedRef<number>
selectedCount: ComputedRef<number>
toggleOption: (option: { value: string | number }) => void
}
// checkbox group
const checkboxGroup = inject<CheckboxGroupContext>('checkboxGroup', {
modelValue: computed(() => []),
disabled: computed(() => false),
max: computed(() => 0),
selectedCount: computed(() => 0),
toggleOption: () => {},
})
//
const isChecked = computed(() => {
const modelValue = checkboxGroup.modelValue.value
return modelValue.includes(props.name)
})
//
const isDisabled = computed(() => {
const max = checkboxGroup.max.value
const selectedCount = checkboxGroup.selectedCount.value
// group
return (
props.disabled ||
checkboxGroup.disabled.value ||
(max > 0 && !isChecked.value && selectedCount >= max)
)
})
//
const handleClick = () => {
if (isDisabled.value) return
checkboxGroup.toggleOption({
value: props.name,
})
}
</script>
<style scoped>
.checkbox {
display: inline-flex;
align-items: center;
cursor: pointer;
font-size: 28rpx;
}
.checkbox--disabled {
cursor: not-allowed;
opacity: 0.5;
}
.checkbox__icon {
width: 40rpx;
height: 40rpx;
border: 2rpx solid #dcdfe6;
border-radius: 4rpx;
display: flex;
align-items: center;
justify-content: center;
margin-right: 8rpx;
transition: all 0.2s;
}
.checkbox__icon--checked {
background-color: #0083ff;
border-color: #0083ff;
}
.checkbox__icon-check {
color: #fff;
font-size: 32rpx;
}
.checkbox__label {
line-height: 1;
}
.checkbox-active {
background-color: #0083ff;
border-color: #0083ff;
}
.checkbox-disabled {
opacity: 0.5;
cursor: not-allowed !important;
}
</style>

View File

@ -0,0 +1,69 @@
<template>
<view class="checkbox-group">
<slot></slot>
</view>
</template>
<script lang="ts" setup>
import { provide, computed } from 'vue'
const props = defineProps({
modelValue: {
type: Array,
default: () => [],
},
max: {
type: Number,
default: 0,
},
disabled: {
type: Boolean,
default: false,
},
})
const emit = defineEmits(['update:modelValue', 'change'])
//
const innerValue = computed(() => props.modelValue)
//
const toggleOption = (option: { label: string; value: string | number }) => {
const currentValue = innerValue.value
const index = currentValue.indexOf(option.value)
const newValue = [...currentValue]
if (index === -1) {
if (props.max && currentValue.length >= props.max) {
uni.showToast({
title: `最多只能选择${props.max}`,
icon: 'none',
})
return
}
newValue.push(option.value)
} else {
newValue.splice(index, 1)
}
emit('update:modelValue', newValue)
emit('change', newValue)
}
// checkbox
provide('checkboxGroup', {
modelValue: computed(() => props.modelValue),
disabled: computed(() => props.disabled),
max: computed(() => props.max),
selectedCount: computed(() => props.modelValue.length),
toggleOption,
})
</script>
<style scoped lang="scss">
.checkbox-group {
display: flex;
flex-wrap: wrap;
gap: 20rpx;
}
</style>

View File

@ -0,0 +1,158 @@
<template>
<view class="drop-menu" ref="dropMenuRef">
<view class="drop-menu__bar">
<view
v-for="(item, index) in titles"
:key="index"
class="drop-menu__item"
:class="{ 'drop-menu__item--active': index === activeIndex }"
@click="handleTitleClick(index)"
>
<text class="drop-menu__title">{{ item }}</text>
<text
class="drop-menu__arrow i-carbon-chevron-down"
:class="{ 'drop-menu__arrow--active': index === activeIndex }"
></text>
</view>
</view>
<view class="drop-menu__content-wrapper">
<slot></slot>
</view>
<view
v-if="activeIndex !== -1"
class="drop-menu__mask"
:style="{ top: maskTop }"
@click="closeDropMenu"
></view>
</view>
</template>
<script lang="ts" setup>
import { ref, provide } from 'vue'
const props = defineProps({
zIndex: {
type: Number,
default: 10,
},
duration: {
type: Number,
default: 200,
},
direction: {
type: String,
default: 'down',
},
})
//
const titles = ref<string[]>([])
//
const activeIndex = ref(-1)
const maskTop = ref('88px')
//
const addTitle = (title: string) => {
titles.value.push(title)
}
const instance = getCurrentInstance()
const dropMenuRef = ref()
//
const handleTitleClick = (index: number) => {
//
if (activeIndex.value === index) {
activeIndex.value = -1
} else {
//
activeIndex.value = index
}
const query = uni.createSelectorQuery().in(instance.proxy)
query
.select('.drop-menu')
.boundingClientRect((data: { top: number }) => {
maskTop.value = `${data.top}px`
})
.exec()
}
//
const closeDropMenu = () => {
activeIndex.value = -1
}
//
provide('dropMenu', {
activeIndex,
addTitle,
closeDropMenu,
zIndex: props.zIndex,
duration: props.duration,
direction: props.direction,
titles, // titles
})
</script>
<style scoped lang="scss">
.drop-menu {
position: relative;
background: #fff;
z-index: 10;
}
.drop-menu__bar {
position: relative;
display: flex;
height: 88rpx;
background: #fff;
z-index: 12;
}
.drop-menu__item {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
}
.drop-menu__item--active {
color: #0083ff;
}
.drop-menu__title {
font-size: 28rpx;
max-width: 80%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.drop-menu__arrow {
font-size: 20rpx;
margin-left: 8rpx;
transition: transform 0.2s;
}
.drop-menu__arrow--active {
transform: rotate(180deg);
}
.drop-menu__content-wrapper {
position: relative;
width: 100%;
}
.drop-menu__mask {
position: fixed;
width: 100%;
left: 0;
right: 0;
top: 88rpx;
bottom: 0;
background: rgba(0, 0, 0, 0.3);
z-index: 9;
}
</style>

View File

@ -0,0 +1,202 @@
<template>
<view
class="drop-menu-item"
:class="[customClass, { 'drop-menu-item--show': isShow }]"
:style="{
'z-index': zIndex,
'transition-duration': `${duration}ms`,
}"
>
<view class="drop-menu-item__wrapper" :class="{ 'drop-menu-item__wrapper--show': isShow }">
<!-- 默认选项列表 -->
<scroll-view v-if="!$slots.default" scroll-y class="drop-menu-item__content">
<view class="drop-menu-item__option-list">
<view
v-for="(option, index) in options"
:key="index"
class="drop-menu-item__option"
:class="{ 'drop-menu-item__option--active': isOptionActive(option) }"
@click="handleOptionClick(option)"
>
<text class="drop-menu-item__text">{{ getOptionText(option) }}</text>
<text v-if="isOptionActive(option)" class="drop-menu-item__icon"></text>
</view>
</view>
</scroll-view>
<!-- 自定义内容插槽 -->
<view v-else class="drop-menu-item__custom-content">
<slot></slot>
</view>
</view>
</view>
</template>
<script lang="ts" setup>
import { ref, inject, onMounted, computed, watch } from 'vue'
const props = defineProps({
modelValue: {
type: [String, Number, Object],
default: '',
},
title: {
type: String,
required: true,
},
options: {
type: Array,
default: () => [],
},
labelKey: {
type: String,
default: 'text',
},
valueKey: {
type: String,
default: 'value',
},
customClass: {
type: String,
default: '',
},
})
const emit = defineEmits(['update:modelValue', 'change', 'open'])
//
const { activeIndex, addTitle, closeDropMenu, zIndex, duration, direction, titles } = inject(
'dropMenu',
) as any
//
const itemIndex = ref(-1)
//
const isShow = computed(() => activeIndex.value === itemIndex.value)
//
watch(isShow, (newVal) => {
if (newVal) {
emit('open')
}
})
//
const getOptionText = (option: any) => {
if (typeof option === 'object' && props.labelKey) {
return option[props.labelKey]
}
return option
}
//
const getOptionValue = (option: any) => {
if (typeof option === 'object' && props.valueKey) {
return option[props.valueKey]
}
return option
}
//
const isOptionActive = (option: any) => {
const optionValue = getOptionValue(option)
return props.modelValue === optionValue
}
//
const handleOptionClick = (option: any) => {
const value = getOptionValue(option)
emit('update:modelValue', value)
emit('change', value)
closeDropMenu()
}
//
onMounted(() => {
//
itemIndex.value = titles.value.length
//
addTitle(props.title)
})
//
watch(
() => props.title,
(newTitle) => {
//
if (titles.value[itemIndex.value] !== newTitle) {
titles.value[itemIndex.value] = newTitle
}
},
{ immediate: false },
)
</script>
<style scoped>
.drop-menu-item {
position: relative;
width: 100%;
}
.drop-menu-item__wrapper {
position: absolute;
left: 0;
right: 0;
top: 0;
background: #fff;
transform: translateY(-5px);
transition: all 0.25s ease;
overflow: hidden;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1);
opacity: 0;
visibility: hidden;
z-index: 11;
}
.drop-menu-item__wrapper--show {
transform: translateY(0);
opacity: 1;
visibility: visible;
}
.drop-menu-item__content {
max-height: 400rpx;
}
.drop-menu-item__custom-content {
width: 100%;
background: #fff;
transform-origin: top;
}
.drop-menu-item__option-list {
padding: 12rpx 0;
}
.drop-menu-item__option {
position: relative;
display: flex;
align-items: center;
justify-content: space-between;
padding: 24rpx 32rpx;
line-height: 1.2;
cursor: pointer;
}
.drop-menu-item__option:active {
background-color: #f2f2f2;
}
.drop-menu-item__option--active {
color: #0083ff;
}
.drop-menu-item__text {
font-size: 28rpx;
}
.drop-menu-item__icon {
font-size: 32rpx;
color: #0083ff;
}
</style>

View File

@ -0,0 +1,113 @@
<template>
<view
class="radio"
:class="{
'radio--disabled': isDisabled,
'radio-active': isChecked,
}"
@click="handleClick"
>
<view class="radio__icon" :class="{ 'radio__icon--checked': isChecked }">
<view v-if="isChecked" class="radio__icon-dot"></view>
</view>
<view class="radio__label">
<slot>{{ label }}</slot>
</view>
</view>
</template>
<script lang="ts" setup>
import { computed, inject } from 'vue'
const props = defineProps({
name: {
type: [String, Number],
required: true,
},
label: {
type: String,
default: '',
},
disabled: {
type: Boolean,
default: false,
},
})
interface RadioGroupContext {
modelValue: ComputedRef<string | number>
disabled: ComputedRef<boolean>
toggleOption: (value: string | number) => void
}
// radio group
const radioGroup = inject<RadioGroupContext>('radioGroup', {
modelValue: computed(() => ''),
disabled: computed(() => false),
toggleOption: () => {},
})
//
const isChecked = computed(() => {
return radioGroup.modelValue.value === props.name
})
//
const isDisabled = computed(() => {
return props.disabled || radioGroup.disabled.value
})
//
const handleClick = () => {
if (isDisabled.value) return
radioGroup.toggleOption(props.name)
}
</script>
<style scoped lang="scss">
.radio {
display: inline-flex;
align-items: center;
cursor: pointer;
font-size: 28rpx;
width: 100%;
height: 100%;
justify-content: center;
&--disabled {
cursor: not-allowed;
opacity: 0.5;
}
&__icon {
width: 40rpx;
height: 40rpx;
border: 2rpx solid #dcdfe6;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin-right: 8rpx;
transition: all 0.2s;
&--checked {
border-color: #0083ff;
}
}
&__icon-dot {
width: 20rpx;
height: 20rpx;
background-color: #0083ff;
border-radius: 50%;
}
&__label {
line-height: 1;
}
}
.radio-active {
color: #0083ff;
}
</style>

View File

@ -0,0 +1,43 @@
<template>
<view class="radio-group">
<slot></slot>
</view>
</template>
<script lang="ts" setup>
import { provide, computed } from 'vue'
const props = defineProps({
modelValue: {
type: [String, Number],
default: '',
},
disabled: {
type: Boolean,
default: false,
},
})
const emit = defineEmits(['update:modelValue', 'change'])
//
const toggleOption = (value: string | number) => {
emit('update:modelValue', value)
emit('change', value)
}
// radio
provide('radioGroup', {
modelValue: computed(() => props.modelValue),
disabled: computed(() => props.disabled),
toggleOption,
})
</script>
<style scoped lang="scss">
.radio-group {
display: flex;
flex-wrap: wrap;
gap: 20rpx;
}
</style>

View File

@ -1,6 +1,5 @@
<template>
<view class="table">
<!-- Table Header -->
<view class="table-header">
<view
v-for="(column, index) in columns"
@ -28,13 +27,11 @@
<script>
export default {
props: {
// Columns definition: array of column objects
columns: {
type: Array,
required: true,
default: () => [],
},
// Table data: array of rows
tableData: {
type: Array,
required: true,
@ -49,6 +46,7 @@ export default {
overflow: hidden;
width: calc(100% - 4rpx);
border: 2rpx solid #eee;
height: 100%;
}
.table-header {

View File

@ -9,21 +9,25 @@
</route>
<template>
<view class="flex flex-col h-screen">
<wd-navbar
<Navbar
title="一键填报"
left-arrow
@click-left="navigatorBack"
safeAreaInsetTop
:bordered="false"
custom-class="bg-transparent! z-[99]"
></wd-navbar>
class="bg-transparent"
></Navbar>
<view class="flex-1 bg-[#f8f8f8] pb-safe flex flex-col items-center pt-[48rpx]">
<wd-badge modelValue="12">
<wd-button plain custom-class="w-[188rpx]! h-[58rpx]! min-w-[unset]!" @click="show = true">
<Badge :value="badgeValue">
<button
plain
class="w-[188rpx]! h-[58rpx]! min-w-[unset]! text-[24rpx]! flex! items-center! justify-center! rounded-[88rpx]! color-[#1580FF]! border-[#1580FF]! border-[2rpx]"
@click="show = true"
>
条件筛选
<wd-icon name="arrow-down"></wd-icon>
</wd-button>
</wd-badge>
<view class="i-carbon-chevron-down"></view>
</button>
</Badge>
<image
class="w-[286rpx] h-[286rpx] mt-[134rpx] mix-blend-multiply"
@ -36,12 +40,16 @@
<script lang="ts" setup>
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 { ref } from 'vue'
const navigatorBack = () => {
uni.navigateBack()
}
const show = ref(false)
const badgeValue = ref(12)
</script>
<style lang="scss" scoped>

View File

@ -4,6 +4,7 @@
style: {
navigationStyle: 'custom',
},
needLogin: true,
}
</route>
<template>

View File

@ -8,7 +8,7 @@
</route>
<template>
<view class="wraper overflow-hidden flex flex-col" :bordered="false">
<wd-navbar title="城市列表" left-arrow @click-left="navigatorBack" safeAreaInsetTop></wd-navbar>
<Navbar title="城市列表" left-arrow @click-left="navigatorBack" safeAreaInsetTop />
<wd-index-bar sticky class="overflow-y h-0 flex-auto">
<view v-for="item in cities" :key="item.letter">
<wd-index-anchor :index="item.letter" />
@ -29,6 +29,7 @@
import { useCityStore } from '@/store/city'
import { useUserStore } from '@/store/user'
import { City } from '@/types/app-type'
import Navbar from '@/pages-sub/components/navbar/Navbar.vue'
const cityStore = useCityStore()
const userStore = useUserStore()

View File

@ -23,7 +23,7 @@
<script setup lang="ts">
import MessageBox from '../../components/MessageBox.vue'
import WXXTable from '@/pages-sub/home/components/Table.vue'
import WXXTable from '@/pages-sub/components/table/Table.vue'
import { getUniversityListByProvince } from '@/service/index/api'
const props = defineProps({

View File

@ -23,7 +23,7 @@
<wd-action-sheet v-model="show" title="">
<view class="px-[32rpx]">
<CustomPickerView :list="pickList" v-model="pickValue" />
<CustomPickerView :list="pickList" v-model:modelValue="pickValue" />
</view>
<view class="flex items-center justify-between px-[32rpx]">
<view class="cancel-btn" @click="show = false">取消</view>
@ -34,7 +34,7 @@
</template>
<script lang="ts" setup>
import WXXTable from '@/pages-sub/home/components/Table.vue'
import WXXTable from '@/pages-sub/components/table/Table.vue'
import { getAdmissionMark } from '@/service/index/api'
import { useUserStore } from '@/store'
import CustomPickerView from '@/pages-sub/components/CustomPickerView.vue'

View File

@ -26,7 +26,7 @@
<wd-action-sheet v-model="show" title="">
<view class="px-[32rpx]">
<CustomPickerView :list="pickList" v-model="pickValue" />
<CustomPickerView :list="pickList" v-model:modelValue="pickValue" />
</view>
<view class="flex items-center justify-between px-[32rpx]">
<view class="cancel-btn" @click="show = false">取消</view>
@ -37,7 +37,7 @@
</template>
<script lang="ts" setup>
import WXXTable from '@/pages-sub/home/components/Table.vue'
import WXXTable from '@/pages-sub/components/table/Table.vue'
import { getPlanProList } from '@/service/index/api'
import CustomPickerView from '@/pages-sub/components/CustomPickerView.vue'
import { useUserStore } from '@/store'

View File

@ -23,7 +23,7 @@
<wd-action-sheet v-model="show" title="">
<view class="px-[32rpx]">
<CustomPickerView :list="pickList" v-model="pickValue" v-if="pickType === 1" />
<CustomPickerView :list="pickList" v-model:modelValue="pickValue" v-if="pickType === 1" />
</view>
<view class="py-[32rpx] flex flex-col items-center justify-center">
<text class="text-[#303030] text-[36rpx] font-bold mb-[50rpx]">省份</text>
@ -44,7 +44,7 @@
</template>
<script lang="ts" setup>
import WXXTable from '@/pages-sub/home/components/Table.vue'
import WXXTable from '@/pages-sub/components/table/Table.vue'
import { getPlanProList } from '@/service/index/api'
import { useUserStore } from '@/store'
import Region from '@/pages-sub/home/components/Region.vue'

View File

@ -8,21 +8,19 @@
</route>
<template>
<view class="flex flex-col">
<wd-navbar
safeAreaInsetTop
custom-class="custom-background"
<view class="flex flex-col h-screen">
<Navbar
class="bg-white"
:bordered="false"
left-arrow
fixed
placeholder
@click-left="navigatorBack"
title="招生简章"
></wd-navbar>
/>
<text class="font-semibold text-[28rpx] text-[#1F2329] mx-auto">
{{ detail?.title }}
</text>
<wd-divider custom-class="my-[16rpx]"></wd-divider>
<view class="w-full h-[1px] bg-[#E5E5E5] my-[16rpx]"></view>
<scroll-view class="flex-1 flex justify-center" :scroll-y="true" :scroll-x="true">
<view class="px-[32rpx]" v-html="detail?.content"></view>
</scroll-view>
@ -31,6 +29,7 @@
<script lang="ts" setup>
import { getRecruitsDetail } from '@/service/index/api'
import Navbar from '@/pages-sub/components/navbar/Navbar.vue'
const navigatorBack = () => {
uni.navigateBack()

View File

@ -4,10 +4,6 @@
navigationStyle: 'custom',
},
needLogin: true,
usingComponents: {
'wd-checkbox-group': 'wot-design-uni/components/wd-checkbox-group/wd-checkbox-group.vue',
'wd-checkbox': 'wot-design-uni/components/wd-checkbox/wd-checkbox.vue',
},
}
</route>
@ -23,7 +19,7 @@
:auto-show-system-loading="true"
>
<template #top>
<wd-navbar
<Navbar
safeAreaInsetTop
custom-class="bg-white!"
:bordered="false"
@ -42,20 +38,22 @@
custom-input-class="h-full flex items-center"
/>
</template>
</wd-navbar>
<wd-drop-menu>
<wd-drop-menu-item
</Navbar>
<drop-menu>
<drop-menu-item
v-for="item in subMenu"
:key="item.id"
:title="item.title"
@open="handleOpenSubMenu(item.id)"
custom-class="flex items-center"
>
<Region v-show="currentMenu === 1" @changeName="handleRegionChange" />
<UniType v-show="currentMenu === 2" @changeName="handleUniTypeChange" />
<Nature v-show="currentMenu === 3" @changeName="handleNatureChange" />
</wd-drop-menu-item>
</wd-drop-menu>
<view class="pt-[32rpx]">
<Region v-if="currentMenu === 1" @changeName="handleRegionChange" />
<Nature v-if="currentMenu === 2" @changeName="handleNatureChange" />
<UniType v-if="currentMenu === 3" @changeName="handleUniTypeChange" />
</view>
</drop-menu-item>
</drop-menu>
</template>
<view
class="item-wrapper"
@ -93,9 +91,12 @@
</template>
<script lang="ts" setup>
import DropMenu from '@/pages-sub/components/drop-menu/DropMenu.vue'
import DropMenuItem from '@/pages-sub/components/drop-menu/DropMenuItem.vue'
import Region from '@/pages-sub/home/components/Region.vue'
import UniType from '@/pages-sub/home/components/UniType.vue'
import Nature from '@/pages-sub/home/components/Nature.vue'
import Navbar from '@/pages-sub/components/navbar/Navbar.vue'
import { getUniversityList } from '@/service/index/api'
const searchValue = ref('')

View File

@ -8,21 +8,20 @@
</route>
<template>
<view class="pb-safe flex flex-col">
<view class="flex flex-col h-screen">
<view class="relative">
<wd-navbar
<Navbar
safeAreaInsetTop
custom-class="bg-transparent! custom-background"
bg-color="transparent"
:bordered="false"
left-arrow
fixed
placeholder
@click-left="navigatorBack"
></wd-navbar>
<view class="custom-background h-[200rpx] w-full absolute top-0 left-0 z-[1]"></view>
content-class="justify-between"
></Navbar>
<view class="custom-background h-[200rpx] w-full absolute top-0 left-0 z-[-1]"></view>
</view>
<scroll-view class="flex-1 flex flex-col" :scroll-y="true">
<scroll-view class="flex-1 flex flex-col pb-safe" :scroll-y="true">
<view class="flex items-center p-[32rpx]" hover-class="none">
<image
class="w-[104rpx] h-[104rpx]"
@ -100,6 +99,8 @@ import EnrollmentIntro from './components/EnrollmentIntro.vue'
import EnrollmentMark from './components/EnrollmentMark.vue'
import Situation from './components/Situation.vue'
import zTabs from '@/pages-sub/uni_modules/z-tabs/components/z-tabs/z-tabs.vue'
import Navbar from '@/pages-sub/components/navbar/Navbar.vue'
import {
getUniversityInfo,
getUnCollectionList,

View File

@ -17,11 +17,11 @@
{{ item.name }}
</view>
</view>
<view class="flex-1 py-[24rpx] h-[50vh] overflow-y-auto">
<view class="flex-1 pb-[24rpx] h-[50vh] overflow-y-auto">
<Phase v-show="currentMenu === 1" />
<Region v-show="currentMenu === 2" />
<UniType v-show="currentMenu === 3" />
<Nature v-show="currentMenu === 4" />
<Region class="custom-wrapper" v-show="currentMenu === 2" />
<UniType class="custom-wrapper" v-show="currentMenu === 3" />
<Nature class="custom-wrapper" v-show="currentMenu === 4" />
</view>
</view>
<view class="pt-[32rpx] px-[32rpx] wei-xin-pt box-shadow">
@ -104,3 +104,11 @@ const changeMenu = (item: { id: number; name: string }) => {
border-top: 2rpx solid #f5f5f5;
}
</style>
<style lang="scss">
.checkbox {
width: 240rpx !important;
height: 60rpx !important;
background: #f7f8fa !important;
}
</style>

View File

@ -10,7 +10,7 @@
<script lang="ts" setup>
import { getNature } from '@/service/index/api'
import CheckGroup from './checkGroup/CheckGroup.vue'
import CheckGroup from '@/pages-sub/components/check-group/CheckGroup.vue'
const infoList = ref()
@ -25,9 +25,7 @@ const defaultInfo = ref<string[]>([])
const emits = defineEmits(['changeName'])
const handleChange = (val: any) => {
const names = infoList.value
.filter((item) => val.value.includes(item.id))
.map((item) => item.name)
const names = infoList.value.filter((item) => val.includes(item.id)).map((item) => item.name)
emits('changeName', names)
}
</script>

View File

@ -1,22 +1,10 @@
<template>
<view class="">
<wd-radio-group
v-model="choosePhase"
cell
inline
custom-class="flex flex-wrap gap-[32rpx] justify-items-center"
checked-color="#1580FF"
>
<wd-radio
v-for="item in phaseList"
:key="item.code"
:value="item.code"
shape="button"
custom-class="w-[240rpx]! h-[60rpx] p-0! mr-0! radio-item-border"
>
<view class="mt-[32rpx]">
<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 }}
</wd-radio>
</wd-radio-group>
</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]"
@ -29,6 +17,8 @@
<script lang="ts" setup>
import { getUniversityLevel } from '@/service/index/api'
import RadioGroup from '@/pages-sub/components/radio-group/RadioGroup.vue'
import Radio from '@/pages-sub/components/radio-group/Radio.vue'
defineOptions({
options: {
@ -48,26 +38,33 @@ const choosePhase = ref('')
</script>
<style lang="scss">
:deep(.radio-item-border) {
border: 2rpx solid #fff !important;
.wd-icon-check-bold {
:deep(.custom-radio-group) {
display: flex;
flex-wrap: wrap;
gap: 32rpx;
background-color: #fff;
justify-content: center;
}
:deep(.custom-radio) {
width: 240rpx;
height: 60rpx;
background-color: #f7f8fa;
border-radius: 8rpx;
display: flex;
align-items: center;
justify-content: center;
border: 2rpx solid #f7f8fa;
.radio__icon {
display: none;
}
> .wd-radio__label {
display: flex !important;
align-items: center !important;
justify-content: center !important;
width: 100% !important;
height: 100% !important;
padding: 16rpx 96rpx !important;
line-height: unset !important;
background-color: #f7f8fa !important;
border-radius: 8rpx !important;
.radio-active {
background-color: rgba(21, 128, 255, 0.1) !important;
border-color: #1580ff !important;
border: 2rpx solid #1580ff;
border-radius: 8rpx;
}
}
:deep(.wd-radio__shape) {
display: none !important;
}
</style>

View File

@ -4,7 +4,7 @@
<script lang="ts" setup>
import { getRegionInfo } from '@/service/index/api'
import CheckGroup from './checkGroup/CheckGroup.vue'
import CheckGroup from '@/pages-sub/components/check-group/CheckGroup.vue'
defineOptions({
options: {
styleIsolation: 'shared',
@ -28,19 +28,8 @@ getRegionInfo().then((res) => {
const emits = defineEmits(['change', 'changeName'])
const handleChange = (val: any) => {
const names = regionList.value
.filter((item) => val.value.includes(item.code))
.map((item) => item.name)
const names = regionList.value.filter((item) => val.includes(item.code)).map((item) => item.name)
emits('changeName', names)
emits('change', val)
}
</script>
<style lang="scss">
:deep(.checkbox-item-border) {
border: 2rpx solid #fff;
> .wd-icon-check-bold {
display: none !important;
}
}
</style>

View File

@ -10,7 +10,7 @@
<script lang="ts" setup>
import { getUniversityType } from '@/service/index/api'
import CheckGroup from './checkGroup/CheckGroup.vue'
import CheckGroup from '@/pages-sub/components/check-group/CheckGroup.vue'
const infoList = ref()
getUniversityType().then((res) => {
@ -24,9 +24,7 @@ const defaultInfo = ref<string[]>([])
const emits = defineEmits(['change', 'changeName'])
const handleChange = (val: any) => {
const names = infoList.value
.filter((item) => val.value.includes(item.id))
.map((item) => item.name)
const names = infoList.value.filter((item) => val.includes(item.id)).map((item) => item.name)
emits('changeName', names)
emits('change', val)
}

View File

@ -1,66 +0,0 @@
<template>
<wd-checkbox-group
v-model="defValue"
custom-class="flex flex-wrap gap-[16rpx] px-[32rpx] pb-[16rpx] items-center"
checked-color="#1580FF"
@change="handleChange"
v-bind="$attrs"
>
<wd-checkbox
v-for="item in list"
:key="item[valueKey]"
:model-value="item[valueKey]"
cell
shape="button"
custom-class="w-auto! h-[76rpx] p-0! mr-0!"
custom-label-class="min-w-[152rpx]! h-[76rpx]! rounded-[8rpx]! checkbox-item-border bg-[#f7f8fa]!"
>
{{ item[labelKey] }}
</wd-checkbox>
</wd-checkbox-group>
</template>
<script lang="ts" setup>
const props = defineProps({
list: {
type: Array,
default: () => [],
},
labelKey: {
type: String,
default: 'name',
},
valueKey: {
type: String,
default: 'code',
},
defaultValue: {
type: Array<string>,
default: () => [],
},
})
defineOptions({
options: {
styleIsolation: 'shared',
},
})
const emits = defineEmits(['change'])
const defValue = ref<string[]>(props.defaultValue)
const handleChange = (val: unknown) => {
emits('change', val)
}
</script>
<style lang="scss" scoped>
:deep(.checkbox-item-border) {
border: 2rpx solid #f7f8fa !important;
> .wd-icon-check-bold {
display: none !important;
}
}
:deep(.wd-checkbox.is-button.is-checked .wd-checkbox__label) {
border: 2rpx solid #1580ff !important;
}
</style>

View File

@ -3,16 +3,12 @@
layout: 'page',
style: {
navigationStyle: 'custom',
usingComponents: {
'wd-checkbox-group': 'wot-design-uni/components/wd-checkbox-group/wd-checkbox-group.vue',
'wd-checkbox': 'wot-design-uni/components/wd-checkbox/wd-checkbox.vue',
},
},
}
</route>
<template>
<view class="h-screen overflow-hidden flex flex-col bg-[#F8F8F8]" :bordered="false">
<wd-navbar title="成绩填写" left-arrow @click-left="navigatorBack" safeAreaInsetTop></wd-navbar>
<Navbar title="成绩填写" left-arrow @click-left="navigatorBack" safeAreaInsetTop />
<view class="px-[32rpx] pt-[47rpx] flex flex-col" hover-class="none">
<text class="text-[22rpx] text-[#636363] text-normal" :selectable="false" :decode="false">
为了使推荐更准确请您认真填写
@ -53,24 +49,23 @@
<text class="" :selectable="false" :decode="false">首选科目</text>
<text class="text-[24rpx] text-gray">({{ requireSubjectList.length }}选1)</text>
</view>
<wd-radio-group
<RadioGroup
v-model="requireSubject"
cell
inline
custom-class="grid md:grid-cols-4 grid-cols-3 gap-[32rpx] justify-items-center bg-[#F8F8F8]!"
class="custom-radio-group"
checked-color="#1580FF"
>
<wd-radio
<Radio
v-for="item in requireSubjectList"
:key="item.code"
:value="item.code"
:name="item.code"
shape="button"
custom-class="w-[152rpx]! h-[76rpx] p-0! mr-0! "
custom-label-class="w-[152rpx]! h-[76rpx]! rounded-[8rpx]! checkbox-item-border"
class="custom-radio"
>
{{ item.name }}
</wd-radio>
</wd-radio-group>
</Radio>
</RadioGroup>
</view>
<view class="mt-[32rpx] px-[32rpx]" hover-class="none">
@ -80,24 +75,16 @@
({{ optionalSubjectList.length }}{{ requireSubjectList.length > 0 ? 2 : 3 }})
</text>
</view>
<wd-checkbox-group
v-model="optionalSubject"
custom-class="grid md:grid-cols-4 grid-cols-3 gap-[32rpx] justify-items-center bg-[#F8F8F8]!"
:max="3"
checked-color="#1580FF"
>
<wd-checkbox
<CheckboxGroup v-model="optionalSubject" :max="3" checked-color="#1580FF">
<Checkbox
v-for="item in optionalSubjectList"
:key="item.code"
:model-value="item.code"
cell
shape="button"
custom-class="w-[152rpx]! h-[76rpx] p-0! mr-0!"
custom-label-class="w-[152rpx]! h-[76rpx]! rounded-[8rpx]! checkbox-item-border bg-white!"
:name="item.code"
class="custom-checkbox"
>
{{ item.name }}
</wd-checkbox>
</wd-checkbox-group>
</Checkbox>
</CheckboxGroup>
</view>
<wd-button
block
@ -113,6 +100,11 @@
<script lang="ts" setup>
import { useUserStore } from '@/store/user'
import Navbar from '@/pages-sub/components/navbar/Navbar.vue'
import CheckboxGroup from '@/pages-sub/components/check-group/CheckboxGroup.vue'
import Checkbox from '@/pages-sub/components/check-group/Checkbox.vue'
import RadioGroup from '@/pages-sub/components/radio-group/RadioGroup.vue'
import Radio from '@/pages-sub/components/radio-group/Radio.vue'
import {
useRules,
@ -191,33 +183,65 @@ const saveScore = () => {
</script>
<style lang="scss" scoped>
:deep(.checkbox-item-border) {
:deep(.custom-checkbox) {
.checkbox {
width: 152rpx;
height: 76rpx;
background-color: #fff;
border-radius: 8rpx;
display: flex;
align-items: center;
justify-content: center;
border: 2rpx solid #fff;
.wd-icon-check-bold {
}
.checkbox__icon {
display: none;
}
}
:deep(.wd-checkbox.is-button.is-checked .wd-checkbox__label) {
:deep(.checkbox-group) {
display: flex;
flex-wrap: wrap;
gap: 32rpx;
justify-content: center;
background-color: #f8f8f8;
}
:deep(.checkbox-active) {
background-color: rgba(21, 128, 255, 0.1) !important;
border-color: #1580ff !important;
.checkbox__label,
.radio__label {
color: #1580ff !important;
}
}
:deep(.wd-radio__label) {
display: flex !important;
align-items: center !important;
justify-content: center !important;
width: 100% !important;
height: 100% !important;
padding: 0 !important;
line-height: unset !important;
background-color: #fff !important;
border-radius: 8rpx !important;
:deep(.custom-radio-group) {
display: flex;
flex-wrap: wrap;
gap: 32rpx;
justify-items: center;
background-color: #f8f8f8;
}
:deep(.wd-radio__shape) {
display: none !important;
}
:deep(.custom-radio) {
width: 152rpx;
height: 76rpx;
background-color: #fff;
border-radius: 8rpx;
display: flex;
align-items: center;
justify-content: center;
border: 2rpx solid #fff;
:deep(.wd-radio.is-button.is-checked .wd-radio__label) {
.radio__icon {
display: none;
}
.radio-active {
background-color: rgba(21, 128, 255, 0.1) !important;
border-color: #1580ff !important;
border: 2rpx solid #1580ff;
border-radius: 8rpx;
}
}
</style>

View File

@ -1,5 +1,168 @@
<route lang="json5" type="page">
{
layout: 'page',
style: {
navigationStyle: 'custom',
},
}
</route>
<template>
<text>批次线</text>
<view class="flex flex-col h-screen">
<view class="relative">
<Navbar
safeAreaInsetTop
bg-color="transparent"
:bordered="false"
left-arrow
:title="`近4年批次线(${userStore.userInfo.estimatedAchievement.provinceName})`"
@click-left="navigatorBack"
/>
<view class="custom-background h-[200rpx] w-full absolute top-0 left-0 z-[-1]"></view>
</view>
<drop-menu>
<drop-menu-item
:key="1"
:title="searchParams.locationName || '省份'"
custom-class="flex items-center"
>
<Region
:defaultValue="searchParams.locationCode ? [searchParams.locationCode] : []"
:max="1"
@changeName="handleRegionChange"
@change="handleRegionChangeCode"
/>
</drop-menu-item>
<drop-menu-item
:key="2"
:title="searchParams.year || '年份'"
custom-class="flex items-center"
>
<CheckGroup
:list="checkYearList"
:default-value="searchParams.year ? [searchParams.year] : []"
@change="handleYearChange"
labelKey="year"
valueKey="year"
:max="1"
/>
</drop-menu-item>
<drop-menu-item :key="3" title="类别" custom-class="flex items-center">
<UniType
@change="handleUniTypeChange"
:max="1"
:default-value="searchParams.type ? [searchParams.type] : []"
/>
</drop-menu-item>
</drop-menu>
<WXXTable
:columns="columns"
:tableData="lineList"
class="px-[32rpx] mt-[16rpx] pb-safe"
></WXXTable>
</view>
</template>
<script lang="ts" setup></script>
<script lang="ts" setup>
import Navbar from '@/pages-sub/components/navbar/Navbar.vue'
import { useUserStore } from '@/store'
import DropMenu from '@/pages-sub/components/drop-menu/DropMenu.vue'
import DropMenuItem from '@/pages-sub/components/drop-menu/DropMenuItem.vue'
import Region from '@/pages-sub/home/components/Region.vue'
import UniType from '@/pages-sub/home/components/UniType.vue'
import CheckGroup from '@/pages-sub/components/check-group/CheckGroup.vue'
import WXXTable from '@/pages-sub/components/table/Table.vue'
import { getBatchList } from '@/service/index/api'
const userStore = useUserStore()
const searchParams = ref({
locationCode: userStore.userInfo.estimatedAchievement.provinceCode,
locationName: userStore.userInfo.estimatedAchievement.provinceName,
year: '',
type: '',
})
const checkYearList = ref([])
const navigatorBack = () => {
uni.navigateBack()
}
const handleRegionChange = (val) => {
searchParams.value.locationName = val.join(',')
}
const handleRegionChangeCode = (val) => {
searchParams.value.locationCode = val[0]
getBatchListData()
}
const handleUniTypeChange = (val) => {
searchParams.value.type = val[0]
getBatchListData()
}
const handleYearChange = (val) => {
let _yearList = []
if (val.length > 1 && val.some((item) => item === '')) {
_yearList = val.filter((item) => item !== '')
} else {
_yearList = val
}
searchParams.value.year = _yearList.join(',')
getBatchListData()
}
const columns = [
{ name: '地区', key: 'province_name', width: '14%' },
{ name: '年份', key: 'year', width: '23%' },
{ name: '类别', key: 'subject_name', width: '23%' },
{ name: '批次', key: 'batch_name', width: '23%' },
{ name: '分数线', key: 'score', width: '17%' },
]
type LineItem = {
batch_id: number
batch_name: string
province_code: number
province_name: string
score: string
subject_id: number
subject_name: string
year: number
}
const lineList = ref<LineItem[]>([])
const getBatchListData = () => {
getBatchList({
locationCode: searchParams.value.locationCode,
year: searchParams.value.year === '不限' ? '' : searchParams.value.year,
type: searchParams.value.type,
}).then((resp) => {
if (resp.code === 200 && resp.result !== '暂无数据') {
const _result = resp.result as {
configList: { yearList: { year: string; check: boolean }[] }
list: LineItem[]
}
checkYearList.value = _result.configList.yearList
lineList.value = _result.list
} else if (resp.code === 200 && resp.result === '暂无数据') {
lineList.value = []
}
})
}
onBeforeMount(() => {
getBatchListData()
})
</script>
<style lang="scss" scoped>
@import '@/pages-sub/home/styles/navbar-background.scss';
</style>

View File

@ -67,7 +67,7 @@
<script lang="ts" setup>
import MessageBox from '@/pages-sub/home/components/MessageBox.vue'
import WXXTable from '@/pages-sub/home/components/Table.vue'
import WXXTable from '@/pages-sub/components/table/Table.vue'
import { getMajorCourse } from '@/service/index/api'
const props = defineProps({

View File

@ -51,8 +51,8 @@
<wd-action-sheet v-model="show" title="">
<view class="px-[32rpx]">
<custom-picker-view
v-model="provinceCode"
<CustomPickerView
v-model:modelValue="provinceCode"
:list="provinceList"
value-key="code"
label-key="ssmc"

View File

@ -9,14 +9,14 @@
<template>
<view class="flex flex-col h-screen">
<wd-navbar
<Navbar
title="详细信息"
left-arrow
@click-left="navigatorBack"
safeAreaInsetTop
:bordered="false"
custom-class="bg-transparent! z-[99]"
></wd-navbar>
/>
<view class="flex-1 overflow-auto pb-safe">
<view class="flex flex-col px-[32rpx]">
<text class="font-semibold text-[28rpx] text-[#1F2329]">
@ -29,7 +29,7 @@
<text class="text-[24rpx]">来源:&nbsp;{{ newsDetail.author }}</text>
</view>
</view>
<wd-divider custom-class="my-[16rpx]"></wd-divider>
<view class="w-full h-[1px] bg-[#E5E5E5] my-[16rpx]"></view>
<view class="px-[32rpx]" v-html="newsDetail.detail"></view>
</view>
</view>
@ -37,8 +37,8 @@
<script lang="ts" setup>
import { useCityNewDetail, newsDetail } from '@/hooks/useCityInfoHook'
import wdNavbar from 'wot-design-uni/components/wd-navbar/wd-navbar.vue'
import wdDivider from 'wot-design-uni/components/wd-divider/wd-divider.vue'
import Navbar from '@/pages-sub/components/navbar/Navbar.vue'
const navigatorBack = () => {
uni.navigateBack()

View File

@ -20,14 +20,14 @@
<!-- 需要固定在顶部不滚动的view放在slot="top"的view中如果需要跟着滚动则不要设置slot="top" -->
<template #top>
<view class="relative h-max" hover-class="none" :hover-stop-propagation="false">
<wd-navbar
<Navbar
title="高考头条"
left-arrow
@click-left="navigatorBack"
safeAreaInsetTop
:bordered="false"
custom-class="bg-transparent! z-[99]"
></wd-navbar>
/>
</view>
</template>
<view
@ -59,6 +59,7 @@
<script lang="ts" setup>
import { getNewsList } from '@/service/index/api'
import { useUserStore } from '@/store/user'
import Navbar from '@/pages-sub/components/navbar/Navbar.vue'
const navigatorBack = () => {
uni.navigateBack()

View File

@ -19,21 +19,24 @@
<!-- 需要固定在顶部不滚动的view放在slot="top"的view中如果需要跟着滚动则不要设置slot="top" -->
<template #top>
<view class="relative h-[400rpx]" hover-class="none" :hover-stop-propagation="false">
<wd-navbar
<Navbar
title="院校排行榜"
left-arrow
@click-left="navigatorBack"
safeAreaInsetTop
:bordered="false"
custom-class="bg-transparent! z-[99]"
></wd-navbar>
<image class="absolute top-0" src="@/pages-sub/static/images/schoolRank/background.svg" />
bgColor="transparent"
/>
<image
class="h-[78rpx] w-[270rpx] absolute top-[249rpx] left-[102rpx]"
class="absolute top-0 z-[-1]"
src="@/pages-sub/static/images/schoolRank/background.svg"
/>
<image
class="h-[78rpx] w-[270rpx] absolute top-[249rpx] left-[102rpx] z-[-1]"
src="@/pages-sub/static/images/schoolRank/title.svg"
/>
<image
class="h-[190rpx] w-[190rpx] absolute top-[194rpx] left-[460rpx] mix-blend-multiply"
class="h-[190rpx] w-[190rpx] absolute top-[194rpx] left-[460rpx] mix-blend-multiply z-[-1]"
src="@/pages-sub/static/images/schoolRank/trophy.jpg"
/>
</view>
@ -97,6 +100,7 @@
<script lang="ts" setup>
import { getUniversityRank, getUnSortType } from '@/service/index/api'
import zTabs from '@/pages-sub/uni_modules/z-tabs/components/z-tabs/z-tabs.vue'
import Navbar from '@/pages-sub/components/navbar/Navbar.vue'
type UnSortType = { type: number; name: string }[]

View File

@ -1,13 +1,3 @@
:deep(.wd-navbar__content) {
display: flex;
align-items: center;
.wd-navbar__title {
display: flex;
align-items: center;
margin-left: 112rpx;
}
}
:deep(.wd-input__prefix) {
line-height: 1 !important;
}

View File

@ -138,7 +138,8 @@
"layout": "page",
"style": {
"navigationStyle": "custom"
}
},
"needLogin": true
},
{
"path": "home/career/info",
@ -170,11 +171,7 @@
"style": {
"navigationStyle": "custom"
},
"needLogin": true,
"usingComponents": {
"wd-checkbox-group": "wot-design-uni/components/wd-checkbox-group/wd-checkbox-group.vue",
"wd-checkbox": "wot-design-uni/components/wd-checkbox/wd-checkbox.vue"
}
"needLogin": true
},
{
"path": "home/college/info",
@ -201,16 +198,16 @@
"type": "page",
"layout": "page",
"style": {
"navigationStyle": "custom",
"usingComponents": {
"wd-checkbox-group": "wot-design-uni/components/wd-checkbox-group/wd-checkbox-group.vue",
"wd-checkbox": "wot-design-uni/components/wd-checkbox/wd-checkbox.vue"
}
"navigationStyle": "custom"
}
},
{
"path": "home/line/index",
"type": "page"
"type": "page",
"layout": "page",
"style": {
"navigationStyle": "custom"
}
},
{
"path": "home/major/index",

View File

@ -1,7 +1,7 @@
<template>
<scroll-view class="" :scroll-y="true">
<view class="gradient-background relative">
<wd-navbar safeAreaInsetTop custom-class="bg-transparent!" :bordered="false">
<Navbar safeAreaInsetTop bg-color="transparent" :bordered="false">
<template #left>
<navigator open-type="navigate" class="left-icon" url="/pages-sub/home/city/index">
<text
@ -18,7 +18,7 @@
<image class="w-[198rpx] h-[28rpx]" src="/static/images/home/app-logo.svg"></image>
</view>
</template>
</wd-navbar>
</Navbar>
<view class="h-[700rpx] w-full custom-background absolute top-0 left-0 z-[-1]"></view>
</view>
<view class="h-full mt-[48rpx]">
@ -34,6 +34,7 @@
<script setup lang="ts">
import TabBar from '@/components/bar/TabBar.vue'
import Navbar from '@/components/navbar/Navbar.vue'
import { useCityInfo } from '@/hooks/useCityInfoHook'
import { useUserStore } from '@/store'

View File

@ -178,3 +178,7 @@ export const getBaseProfession = (params: { KeyWord: string }) => {
export const getProfessionInfo = (params: { id: string }) => {
return http.get('/api/zhiYuan/professiondetails', params)
}
export const getBatchList = (params: { locationCode: string; year: string; type: string }) => {
return http.get('/api/zhiYuan/batchList', params)
}