feat: 查位次
parent
be40ec0395
commit
d1f2b31260
|
|
@ -44,7 +44,7 @@ const subMenus = [
|
||||||
{
|
{
|
||||||
id: 5,
|
id: 5,
|
||||||
name: '查位次',
|
name: '查位次',
|
||||||
path: '/pages-sub/home/rank/index',
|
path: '/pages-evaluation-sub/rank/index',
|
||||||
icon: '/static/images/home/rank.svg',
|
icon: '/static/images/home/rank.svg',
|
||||||
},
|
},
|
||||||
// 查扩缩招
|
// 查扩缩招
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,121 @@
|
||||||
|
<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"
|
||||||
|
:style="checkboxStyle"
|
||||||
|
>
|
||||||
|
{{ 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: () => [],
|
||||||
|
},
|
||||||
|
width: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: '216rpx',
|
||||||
|
},
|
||||||
|
height: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: '60rpx',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
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]
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
// 计算复选框样式
|
||||||
|
const checkboxStyle = computed(() => {
|
||||||
|
const width = typeof props.width === 'number' ? `${props.width}rpx` : props.width
|
||||||
|
const height = typeof props.height === 'number' ? `${props.height}rpx` : props.height
|
||||||
|
return {
|
||||||
|
'--checkbox-width': width,
|
||||||
|
'--checkbox-height': height,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
:deep(.custom-checkbox) {
|
||||||
|
// 定义默认变量
|
||||||
|
--checkbox-width: 216rpx;
|
||||||
|
--checkbox-height: 60rpx;
|
||||||
|
--checkbox-bg: #f7f8fa;
|
||||||
|
--checkbox-radius: 8rpx;
|
||||||
|
|
||||||
|
.checkbox {
|
||||||
|
width: var(--checkbox-width);
|
||||||
|
height: var(--checkbox-height);
|
||||||
|
min-width: var(--checkbox-width);
|
||||||
|
background-color: var(--checkbox-bg);
|
||||||
|
border-radius: var(--checkbox-radius);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border: 2rpx solid var(--checkbox-bg);
|
||||||
|
}
|
||||||
|
.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>
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
// 将px转换为rpx的比例
|
||||||
|
const ratio = 750 / screenWidth
|
||||||
|
|
||||||
|
// 根据平台设置不同的导航栏高度
|
||||||
|
if (platform === 'ios') {
|
||||||
|
return 88 / ratio // iOS 一般是 44pt,转换为px
|
||||||
|
} else if (platform === 'android') {
|
||||||
|
return 96 / ratio // Android 一般是 48dp,转换为px
|
||||||
|
} 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>
|
||||||
|
|
@ -0,0 +1,194 @@
|
||||||
|
<template>
|
||||||
|
<view class="custom-picker">
|
||||||
|
<view class="picker-mask" @touchmove.stop.prevent></view>
|
||||||
|
<picker-view
|
||||||
|
:value="currentIndex"
|
||||||
|
:indicator-style="indicatorStyle"
|
||||||
|
:style="{
|
||||||
|
border: 'none',
|
||||||
|
'border-top': 'none',
|
||||||
|
'border-bottom': 'none',
|
||||||
|
}"
|
||||||
|
@change="handleChange"
|
||||||
|
class="picker-view"
|
||||||
|
:mask-class="'picker-mask'"
|
||||||
|
:indicator-class="'picker-indicator'"
|
||||||
|
>
|
||||||
|
<picker-view-column class="border-none">
|
||||||
|
<view
|
||||||
|
v-for="(item, index) in formattedList"
|
||||||
|
:key="index"
|
||||||
|
class="picker-item"
|
||||||
|
:class="{ 'picker-item-selected': currentIndex[0] === index }"
|
||||||
|
>
|
||||||
|
{{ item }}
|
||||||
|
</view>
|
||||||
|
</picker-view-column>
|
||||||
|
</picker-view>
|
||||||
|
<!-- <view class="picker-indicator-line"></view> -->
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { computed, ref, watch } from 'vue'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: {
|
||||||
|
type: [String, Number, Object],
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
list: {
|
||||||
|
type: Array,
|
||||||
|
required: true,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
|
valueKey: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
labelKey: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
indicatorStyle: {
|
||||||
|
type: String,
|
||||||
|
default: 'height: 50px;',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits(['update:modelValue', 'change'])
|
||||||
|
|
||||||
|
// 格式化列表数据
|
||||||
|
const formattedList = computed(() => {
|
||||||
|
if (!props.list.length) return []
|
||||||
|
|
||||||
|
// 处理简单数组 ['123', '456']
|
||||||
|
if (typeof props.list[0] !== 'object') {
|
||||||
|
return props.list
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理对象数组,使用labelKey
|
||||||
|
if (props.labelKey) {
|
||||||
|
return props.list.map((item) => item[props.labelKey])
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理对象数组,使用valueKey作为显示
|
||||||
|
if (props.valueKey) {
|
||||||
|
return props.list.map((item) => item[props.valueKey])
|
||||||
|
}
|
||||||
|
|
||||||
|
// 默认显示整个对象
|
||||||
|
return props.list
|
||||||
|
})
|
||||||
|
|
||||||
|
// 计算当前选中项的索引
|
||||||
|
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) {
|
||||||
|
return item[props.valueKey] === targetValue
|
||||||
|
}
|
||||||
|
return item === targetValue
|
||||||
|
})
|
||||||
|
|
||||||
|
return [index > -1 ? index : 0]
|
||||||
|
})
|
||||||
|
|
||||||
|
// 处理选择变化
|
||||||
|
const handleChange = (e: any) => {
|
||||||
|
const index = e.detail.value[0]
|
||||||
|
const selectedItem = props.list[index]
|
||||||
|
|
||||||
|
let value = selectedItem
|
||||||
|
if (typeof selectedItem === 'object' && props.valueKey) {
|
||||||
|
value = selectedItem[props.valueKey]
|
||||||
|
}
|
||||||
|
|
||||||
|
emit('update:modelValue', value)
|
||||||
|
emit('change', {
|
||||||
|
value,
|
||||||
|
index,
|
||||||
|
item: selectedItem,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.custom-picker {
|
||||||
|
width: 100%;
|
||||||
|
height: 400rpx;
|
||||||
|
position: relative;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.picker-view {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 覆盖picker-view的默认边框 */
|
||||||
|
.picker-view :deep(.uni-picker-view-indicator),
|
||||||
|
.picker-view :deep(.uni-picker-view-column),
|
||||||
|
.picker-view :deep(.uni-picker-view-group) {
|
||||||
|
border: none !important;
|
||||||
|
border-top: none !important;
|
||||||
|
border-bottom: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.picker-mask {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.picker-indicator {
|
||||||
|
height: 112rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.picker-indicator-line {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
top: 50%;
|
||||||
|
margin-top: -40rpx;
|
||||||
|
height: 112rpx;
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.picker-item {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 34rpx;
|
||||||
|
color: #7c7c7c;
|
||||||
|
transition: all 0.2s;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.picker-item-selected {
|
||||||
|
color: #000;
|
||||||
|
font-weight: 500;
|
||||||
|
transform: scale(1.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 添加触摸反馈 */
|
||||||
|
.picker-view :deep(.uni-picker-view-wrapper) {
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.picker-view :deep(.uni-picker-view-content) {
|
||||||
|
touch-action: pan-y;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,130 @@
|
||||||
|
export const initRankAreaEchart = ({
|
||||||
|
echart,
|
||||||
|
echarts,
|
||||||
|
xAxisData,
|
||||||
|
yAxisData,
|
||||||
|
Score,
|
||||||
|
currentCount,
|
||||||
|
areaIndex,
|
||||||
|
}) => {
|
||||||
|
echart.value.init(echarts, (chart) => {
|
||||||
|
let option = {
|
||||||
|
xAxis: {
|
||||||
|
type: 'category',
|
||||||
|
data: xAxisData,
|
||||||
|
axisLine: {
|
||||||
|
lineStyle: {
|
||||||
|
color: '#E5E5E5',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
color: '#999999',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
type: 'value',
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
containLabel: false,
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
data: yAxisData,
|
||||||
|
type: 'line',
|
||||||
|
smooth: 0.6,
|
||||||
|
smoothMonotone: 'x',
|
||||||
|
symbol: 'none',
|
||||||
|
lineStyle: {
|
||||||
|
width: 2,
|
||||||
|
color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
|
||||||
|
{
|
||||||
|
offset: 0,
|
||||||
|
color: 'rgba(30, 231, 255, 1)',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
offset: 0.33,
|
||||||
|
color: 'rgba(36, 154, 255, 1)',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
offset: 0.66,
|
||||||
|
color: 'rgba(111, 66, 251, 1)',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
offset: 1,
|
||||||
|
color: 'rgba(111, 66, 251, 1)',
|
||||||
|
},
|
||||||
|
]),
|
||||||
|
},
|
||||||
|
areaStyle: {
|
||||||
|
opacity: 1,
|
||||||
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||||
|
{
|
||||||
|
offset: 0,
|
||||||
|
color: 'rgba(17,126,255,0.16)',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
offset: 1,
|
||||||
|
color: 'rgba(17,128,255,0)',
|
||||||
|
},
|
||||||
|
]),
|
||||||
|
},
|
||||||
|
markPoint: {
|
||||||
|
symbol: 'circle',
|
||||||
|
symbolSize: 8,
|
||||||
|
itemStyle: {
|
||||||
|
color: '#4080FF',
|
||||||
|
borderColor: '#259BFF',
|
||||||
|
borderWidth: 2,
|
||||||
|
},
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
xAxis: Score,
|
||||||
|
yAxis: currentCount,
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
position: 'top',
|
||||||
|
color: '#4080FF',
|
||||||
|
fontSize: 12,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
markArea: {
|
||||||
|
itemStyle: {
|
||||||
|
color: 'rgba(64, 128, 255, 0.1)',
|
||||||
|
},
|
||||||
|
data: [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
xAxis: areaIndex + 30,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
xAxis: areaIndex - 30,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
markLine: {
|
||||||
|
symbol: ['none', 'none'],
|
||||||
|
lineStyle: {
|
||||||
|
type: 'dashed',
|
||||||
|
color: '#4080FF',
|
||||||
|
width: 1,
|
||||||
|
opacity: 0.5,
|
||||||
|
},
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
xAxis: Score,
|
||||||
|
label: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
chart.setOption(option)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
<template>
|
||||||
|
<CheckGroup :list="regionList" @change="handleChange" label-key="simplename" v-bind="$attrs" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { getRegionInfo } from '@/service/index/api'
|
||||||
|
import CheckGroup from '@/pages-evaluation-sub/components/check-group/CheckGroup.vue'
|
||||||
|
defineOptions({
|
||||||
|
options: {
|
||||||
|
styleIsolation: 'shared',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
interface Region {
|
||||||
|
code: string
|
||||||
|
name: string
|
||||||
|
parentcode: string
|
||||||
|
simplename: string
|
||||||
|
pinyin: string
|
||||||
|
}
|
||||||
|
const regionList = ref([])
|
||||||
|
getRegionInfo().then((res) => {
|
||||||
|
if (res.code === 200) {
|
||||||
|
regionList.value = res.result as Region[]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const emits = defineEmits(['change', 'changeName'])
|
||||||
|
|
||||||
|
const handleChange = (val: any) => {
|
||||||
|
const names = regionList.value.filter((item) => val.includes(item.code)).map((item) => item.name)
|
||||||
|
emits('changeName', names)
|
||||||
|
emits('change', val)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
<template>
|
||||||
|
<CheckGroup
|
||||||
|
:list="infoList"
|
||||||
|
@change="handleChange"
|
||||||
|
:default-value="defaultInfo"
|
||||||
|
value-key="id"
|
||||||
|
label-key="name"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { getUniversityType } from '@/service/index/api'
|
||||||
|
import CheckGroup from '@/pages-evaluation-sub/components/check-group/CheckGroup.vue'
|
||||||
|
|
||||||
|
const infoList = ref()
|
||||||
|
getUniversityType().then((res) => {
|
||||||
|
if (res.code === 200) {
|
||||||
|
infoList.value = res.result as { id: number; name: string }[]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const defaultInfo = ref<string[]>([])
|
||||||
|
|
||||||
|
const emits = defineEmits(['change', 'changeName'])
|
||||||
|
|
||||||
|
const handleChange = (val: any) => {
|
||||||
|
const names = infoList.value.filter((item) => val.includes(item.id)).map((item) => item.name)
|
||||||
|
emits('changeName', names)
|
||||||
|
emits('change', val)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,257 @@
|
||||||
|
<route lang="json5" type="page">
|
||||||
|
{
|
||||||
|
layout: 'page',
|
||||||
|
style: {
|
||||||
|
navigationStyle: 'custom',
|
||||||
|
},
|
||||||
|
usingComponents: {
|
||||||
|
LEchart: '../uni_modules/lime-echart/components/l-echart/l-echart',
|
||||||
|
},
|
||||||
|
componentPlaceholder: {
|
||||||
|
LEchart: 'view',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</route>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<view class="h-screen flex flex-col">
|
||||||
|
<view class="relative">
|
||||||
|
<Navbar
|
||||||
|
safeAreaInsetTop
|
||||||
|
bg-color="transparent"
|
||||||
|
:bordered="false"
|
||||||
|
left-arrow
|
||||||
|
title="位次查询"
|
||||||
|
@click-left="navigatorBack"
|
||||||
|
content-class="justify-between"
|
||||||
|
></Navbar>
|
||||||
|
<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>
|
||||||
|
|
||||||
|
<view class="px-32rpx">
|
||||||
|
<view class="flex items-center justify-between input-wrapper-class">
|
||||||
|
<input
|
||||||
|
v-model="searchParams.Score"
|
||||||
|
type="number"
|
||||||
|
placeholder="请输入你的高考分数"
|
||||||
|
confirm-type="done"
|
||||||
|
input-mode="numeric"
|
||||||
|
class="flex-auto"
|
||||||
|
/>
|
||||||
|
<view class="text-[#1580FF] text-[24rpx] search-text" @click="handleConfirm">查询</view>
|
||||||
|
</view>
|
||||||
|
<view class="text-[#636363] text-[20rpx] mt-[24rpx]">分数范围:{{ betweenScores }}</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="bg-[#F8F8F8] h-[16rpx] mt-[40rpx]"></view>
|
||||||
|
|
||||||
|
<view class="pt-[40rpx] px-[32rpx] flex flex-col">
|
||||||
|
<text class="font-semibold text-[32rpx]">查询结果</text>
|
||||||
|
<view class="flex flex-col mt-[22rpx]">
|
||||||
|
<view class="text-[24rpx] text-[#636363]">
|
||||||
|
位次区间:
|
||||||
|
<text class="text-[#1580FF]">21559-22548</text>
|
||||||
|
</view>
|
||||||
|
<view class="text-[24rpx] text-[#636363]">
|
||||||
|
建议位次:
|
||||||
|
<text class="text-[#1580FF]">22204</text>
|
||||||
|
</view>
|
||||||
|
<view class="text-[24rpx] text-[#636363]">
|
||||||
|
同分人数:
|
||||||
|
<text class="text-[#1580FF]">690</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="">
|
||||||
|
<LEchart ref="echart" class="h-[300rpx]" v-show="!noData"></LEchart>
|
||||||
|
<view class="flex items-center justify-center flex-col my-[80rpx] relative" v-show="noData">
|
||||||
|
<image
|
||||||
|
src="../static/images/no-data.jpg"
|
||||||
|
mode="scaleToFill"
|
||||||
|
class="w-[300rpx] h-[300rpx]"
|
||||||
|
/>
|
||||||
|
<text class="text-[24rpx] text-[#636363] absolute bottom-[60rpx]">暂无数据</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="flex flex-col p-[24rpx] bg-[#FEF0F0] text-[#F56C6C] mx-[32rpx] border-class">
|
||||||
|
<text class="text-[32rpx] font-bold">*说明</text>
|
||||||
|
<text class="text-[24rpx] mt-[16rpx] text-[22rpx] font-normal">
|
||||||
|
1.位次查询结果根据各省教育考试院发布的一分一段表计算。
|
||||||
|
</text>
|
||||||
|
<text class="text-[24rpx] mt-[16rpx] text-[22rpx] font-normal">
|
||||||
|
2.在正式填报时,请以各省教育考试院发布的数据为准,本平台数据仅供参考
|
||||||
|
</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import Navbar from '@/pages-evaluation-sub/components/navbar/Navbar.vue'
|
||||||
|
import DropMenu from '@/pages-evaluation-sub/components/drop-menu/DropMenu.vue'
|
||||||
|
import DropMenuItem from '@/pages-evaluation-sub/components/drop-menu/DropMenuItem.vue'
|
||||||
|
import Region from './components/Region.vue'
|
||||||
|
import UniType from './components/UniType.vue'
|
||||||
|
import CheckGroup from '@/pages-evaluation-sub/components/check-group/CheckGroup.vue'
|
||||||
|
|
||||||
|
// import lEchart from '@/pages-evaluation-sub/uni_modules/lime-echart/components/l-echart/l-echart.vue'
|
||||||
|
const echarts = require('../uni_modules/lime-echart/static/echarts.min')
|
||||||
|
|
||||||
|
import { getScoreSection } from '@/service/index/api'
|
||||||
|
|
||||||
|
import { useUserStore } from '@/store'
|
||||||
|
import { initRankAreaEchart } from '../composable/rankAreaEchart'
|
||||||
|
|
||||||
|
const userStore = useUserStore()
|
||||||
|
|
||||||
|
const navigatorBack = () => {
|
||||||
|
uni.navigateBack()
|
||||||
|
}
|
||||||
|
|
||||||
|
const searchParams = ref({
|
||||||
|
locationCode: userStore.userInfo.estimatedAchievement.provinceCode || '370000',
|
||||||
|
locationName: userStore.userInfo.estimatedAchievement.provinceName || '山东省',
|
||||||
|
year: '',
|
||||||
|
type: '',
|
||||||
|
Score: '500',
|
||||||
|
})
|
||||||
|
|
||||||
|
const handleConfirm = () => {
|
||||||
|
getScoreSectionData()
|
||||||
|
}
|
||||||
|
|
||||||
|
const checkYearList = ref([])
|
||||||
|
|
||||||
|
const handleRegionChange = (val) => {
|
||||||
|
searchParams.value.locationName = val.join(',')
|
||||||
|
}
|
||||||
|
const handleRegionChangeCode = (val) => {
|
||||||
|
searchParams.value.locationCode = val[0]
|
||||||
|
getScoreSectionData()
|
||||||
|
}
|
||||||
|
|
||||||
|
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(',')
|
||||||
|
getScoreSectionData()
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleUniTypeChange = (val) => {
|
||||||
|
searchParams.value.type = val[0]
|
||||||
|
getScoreSectionData()
|
||||||
|
}
|
||||||
|
|
||||||
|
const betweenScores = ref('')
|
||||||
|
const noData = ref(false)
|
||||||
|
|
||||||
|
const getScoreSectionData = () => {
|
||||||
|
getScoreSection(searchParams.value).then((resp) => {
|
||||||
|
if (resp.code === 200) {
|
||||||
|
const _result = resp.result as {
|
||||||
|
betweenScores: string
|
||||||
|
list: {
|
||||||
|
type: number
|
||||||
|
score: number
|
||||||
|
currentCount: number
|
||||||
|
cumulativeCount: number
|
||||||
|
startRank: number
|
||||||
|
endRank: number
|
||||||
|
}[]
|
||||||
|
configList: { yearList: { year: string; check: boolean }[] }
|
||||||
|
}
|
||||||
|
checkYearList.value = _result.configList.yearList
|
||||||
|
betweenScores.value = _result.betweenScores
|
||||||
|
noData.value = _result.list.length === 0
|
||||||
|
|
||||||
|
if (!noData.value) {
|
||||||
|
const xAxisData = _result.list.map((item) => item.score)
|
||||||
|
const yAxisData = _result.list.map((item) => item.currentCount)
|
||||||
|
|
||||||
|
const areaIndex = xAxisData.findIndex((item) => item === Number(searchParams.value.Score))
|
||||||
|
const currentCount = _result.list.filter(
|
||||||
|
(item) => item.score === Number(searchParams.value.Score),
|
||||||
|
)[0].currentCount
|
||||||
|
console.log(echart.value, echarts)
|
||||||
|
|
||||||
|
initRankAreaEchart({
|
||||||
|
echart,
|
||||||
|
echarts,
|
||||||
|
xAxisData,
|
||||||
|
yAxisData,
|
||||||
|
Score: searchParams.value.Score,
|
||||||
|
currentCount,
|
||||||
|
areaIndex,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const echart = ref(null)
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getScoreSectionData()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '@/pages-evaluation-sub/styles/navbar-background.scss';
|
||||||
|
|
||||||
|
.input-wrapper-class {
|
||||||
|
border-radius: 8rpx;
|
||||||
|
border: 2rpx solid #ededed;
|
||||||
|
padding: 10rpx 24rpx;
|
||||||
|
margin-top: 48rpx;
|
||||||
|
|
||||||
|
.search-text {
|
||||||
|
border-left: 2rpx solid #ededed;
|
||||||
|
padding-left: 24rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.border-class {
|
||||||
|
border-radius: 8rpx;
|
||||||
|
border: 2rpx solid #ffeaea;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
|
|
@ -0,0 +1,13 @@
|
||||||
|
.custom-background {
|
||||||
|
background-image: linear-gradient(
|
||||||
|
173deg,
|
||||||
|
rgb(177, 221, 250) 0,
|
||||||
|
rgb(177, 221, 250) 13%,
|
||||||
|
rgba(255, 255, 255, 1) 80%,
|
||||||
|
rgba(255, 255, 255, 1) 100%
|
||||||
|
);
|
||||||
|
background-position: 50% 50%;
|
||||||
|
background-origin: padding-box;
|
||||||
|
background-clip: border-box;
|
||||||
|
background-size: auto auto;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
:deep(.z-tabs-bottom) {
|
||||||
|
border-bottom: 1px solid #f8f8f8;
|
||||||
|
}
|
||||||
|
|
@ -1,13 +1,16 @@
|
||||||
<template>
|
<template>
|
||||||
<view class="badge">
|
<view class="badge" :class="customClass">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
<view
|
<view
|
||||||
v-show="showBadge"
|
v-show="showBadge"
|
||||||
class="badge__content"
|
class="badge__content"
|
||||||
:class="{
|
:class="[
|
||||||
'badge__content--dot': isDot,
|
{
|
||||||
'badge__content--fixed': !$slots.default,
|
'badge__content--dot': isDot,
|
||||||
}"
|
'badge__content--fixed': !$slots.default,
|
||||||
|
},
|
||||||
|
customContentClass,
|
||||||
|
]"
|
||||||
:style="badgeStyle"
|
:style="badgeStyle"
|
||||||
>
|
>
|
||||||
<block v-if="!isDot">{{ finalContent }}</block>
|
<block v-if="!isDot">{{ finalContent }}</block>
|
||||||
|
|
@ -43,6 +46,14 @@ const props = defineProps({
|
||||||
type: String,
|
type: String,
|
||||||
default: '#fff',
|
default: '#fff',
|
||||||
},
|
},
|
||||||
|
customClass: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
customContentClass: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
// 是否显示徽标
|
// 是否显示徽标
|
||||||
|
|
@ -84,6 +95,10 @@ const badgeStyle = computed(() => {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
|
// 定义默认变量
|
||||||
|
--badge-size: 32rpx;
|
||||||
|
--badge-font-size: 20rpx;
|
||||||
|
--badge-dot-size: 16rpx;
|
||||||
|
|
||||||
&__content {
|
&__content {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
@ -92,21 +107,21 @@ const badgeStyle = computed(() => {
|
||||||
transform: translate(50%, -50%);
|
transform: translate(50%, -50%);
|
||||||
transform-origin: 100% 0%;
|
transform-origin: 100% 0%;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
min-width: 32rpx;
|
min-width: var(--badge-size);
|
||||||
height: 32rpx;
|
height: var(--badge-size);
|
||||||
padding: 0 8rpx;
|
padding: 0 8rpx;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
font-size: 20rpx;
|
font-size: var(--badge-font-size);
|
||||||
line-height: 32rpx;
|
line-height: var(--badge-size);
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
background-color: #ff4d4f;
|
background-color: #ff4d4f;
|
||||||
border-radius: 16rpx;
|
border-radius: calc(var(--badge-size) / 2);
|
||||||
box-shadow: 0 0 0 2rpx #fff;
|
box-shadow: 0 0 0 2rpx #fff;
|
||||||
|
|
||||||
&--dot {
|
&--dot {
|
||||||
width: 16rpx;
|
width: var(--badge-dot-size);
|
||||||
height: 16rpx;
|
height: var(--badge-dot-size);
|
||||||
padding: 0;
|
padding: 0;
|
||||||
min-width: auto;
|
min-width: auto;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
cell
|
cell
|
||||||
shape="button"
|
shape="button"
|
||||||
class="custom-checkbox"
|
class="custom-checkbox"
|
||||||
custom-label-class="min-w-[152rpx]! h-[76rpx]! rounded-[8rpx]! checkbox-item-border bg-[#f7f8fa]!"
|
:style="checkboxStyle"
|
||||||
>
|
>
|
||||||
{{ item[labelKey] }}
|
{{ item[labelKey] }}
|
||||||
</Checkbox>
|
</Checkbox>
|
||||||
|
|
@ -34,6 +34,14 @@ const props = defineProps({
|
||||||
type: Array<string>,
|
type: Array<string>,
|
||||||
default: () => [],
|
default: () => [],
|
||||||
},
|
},
|
||||||
|
width: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: '216rpx',
|
||||||
|
},
|
||||||
|
height: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: '60rpx',
|
||||||
|
},
|
||||||
})
|
})
|
||||||
defineOptions({
|
defineOptions({
|
||||||
options: {
|
options: {
|
||||||
|
|
@ -61,19 +69,36 @@ watch(
|
||||||
defValue.value = [...newVal]
|
defValue.value = [...newVal]
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// 计算复选框样式
|
||||||
|
const checkboxStyle = computed(() => {
|
||||||
|
const width = typeof props.width === 'number' ? `${props.width}rpx` : props.width
|
||||||
|
const height = typeof props.height === 'number' ? `${props.height}rpx` : props.height
|
||||||
|
return {
|
||||||
|
'--checkbox-width': width,
|
||||||
|
'--checkbox-height': height,
|
||||||
|
}
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
:deep(.custom-checkbox) {
|
:deep(.custom-checkbox) {
|
||||||
|
// 定义默认变量
|
||||||
|
--checkbox-width: 216rpx;
|
||||||
|
--checkbox-height: 60rpx;
|
||||||
|
--checkbox-bg: #f7f8fa;
|
||||||
|
--checkbox-radius: 8rpx;
|
||||||
|
|
||||||
.checkbox {
|
.checkbox {
|
||||||
width: 216rpx;
|
width: var(--checkbox-width);
|
||||||
height: 60rpx;
|
height: var(--checkbox-height);
|
||||||
background-color: #f7f8fa;
|
min-width: var(--checkbox-width);
|
||||||
border-radius: 8rpx;
|
background-color: var(--checkbox-bg);
|
||||||
|
border-radius: var(--checkbox-radius);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
border: 2rpx solid #f7f8fa;
|
border: 2rpx solid var(--checkbox-bg);
|
||||||
}
|
}
|
||||||
.checkbox__icon {
|
.checkbox__icon {
|
||||||
display: none;
|
display: none;
|
||||||
|
|
@ -84,9 +109,9 @@ watch(
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
gap: 16rpx;
|
gap: 16rpx;
|
||||||
|
|
||||||
padding: 32rpx 16rpx 16rpx;
|
padding: 32rpx 16rpx 16rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.checkbox-active) {
|
:deep(.checkbox-active) {
|
||||||
border-color: #1580ff !important;
|
border-color: #1580ff !important;
|
||||||
.checkbox__label {
|
.checkbox__label {
|
||||||
|
|
|
||||||
|
|
@ -5,63 +5,60 @@
|
||||||
v-for="(column, index) in columns"
|
v-for="(column, index) in columns"
|
||||||
:key="index"
|
:key="index"
|
||||||
class="table-cell"
|
class="table-cell"
|
||||||
:style="{ width: column.width || 'auto' }"
|
:class="[`text-${column.align || 'center'}`]"
|
||||||
|
:style="{ width: column.width }"
|
||||||
>
|
>
|
||||||
<text>{{ column.name }}</text>
|
<text>{{ column.label }}</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view v-for="(item, index) in tableData" :key="index" class="table-row">
|
<view v-for="(item, index) in data" :key="index" class="table-row">
|
||||||
<view
|
<view
|
||||||
v-for="(column, colIndex) in columns"
|
v-for="(column, colIndex) in columns"
|
||||||
:key="colIndex"
|
:key="colIndex"
|
||||||
class="table-cell"
|
class="table-cell"
|
||||||
:style="{ width: column.width || 'auto' }"
|
:class="[`text-${column.align || 'center'}`]"
|
||||||
|
:style="{ width: column.width }"
|
||||||
>
|
>
|
||||||
<text>{{ item[column.key] }}</text>
|
<text>{{ item[column.prop] }}</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="text-center p-[32rpx]" v-show="tableData.length === 0">暂无数据</view>
|
<view class="text-center p-[32rpx]" v-show="data.length === 0">暂无数据</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script lang="ts" setup>
|
||||||
export default {
|
import { useTable } from './useTable'
|
||||||
props: {
|
|
||||||
columns: {
|
const props = defineProps<{
|
||||||
type: Array,
|
data: any[]
|
||||||
required: true,
|
}>()
|
||||||
default: () => [],
|
|
||||||
},
|
const { columns } = useTable()
|
||||||
tableData: {
|
|
||||||
type: Array,
|
|
||||||
required: true,
|
|
||||||
default: () => [],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.table {
|
.table {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
width: calc(100% - 4rpx);
|
width: 100%;
|
||||||
border: 2rpx solid #eee;
|
border: 2rpx solid #eee;
|
||||||
height: 100%;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.table-header {
|
.table-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
background-color: #f5f5f5;
|
background-color: #f5f5f5;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
min-height: 60rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.table-cell {
|
.table-cell {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
padding: 16rpx;
|
|
||||||
font-size: 20rpx;
|
font-size: 24rpx;
|
||||||
color: #333333;
|
color: #333333;
|
||||||
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.table-header .table-cell {
|
.table-header .table-cell {
|
||||||
|
|
@ -75,7 +72,6 @@ export default {
|
||||||
|
|
||||||
.table-row .table-cell {
|
.table-row .table-cell {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 16rpx;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.table-row:first-child {
|
.table-row:first-child {
|
||||||
|
|
@ -85,4 +81,16 @@ export default {
|
||||||
.table-cell:not(:last-child) {
|
.table-cell:not(:last-child) {
|
||||||
border-right: 1px solid #ddd;
|
border-right: 1px solid #ddd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.text-left {
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-center {
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-right {
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
<template>
|
||||||
|
<view style="display: none">
|
||||||
|
<!-- 这是一个虚拟组件,不需要实际渲染内容 -->
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { onMounted } from 'vue'
|
||||||
|
import { useTableInject } from './useTable'
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
prop: string
|
||||||
|
label: string
|
||||||
|
width?: string
|
||||||
|
align?: 'left' | 'center' | 'right'
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const { addColumn } = useTableInject()
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
addColumn({
|
||||||
|
prop: props.prop,
|
||||||
|
label: props.label,
|
||||||
|
width: props.width,
|
||||||
|
align: props.align,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.table-cell {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 16rpx;
|
||||||
|
font-size: 20rpx;
|
||||||
|
color: #333333;
|
||||||
|
border-right: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-cell:last-child {
|
||||||
|
border-right: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-left {
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-center {
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-right {
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
import { inject, provide, ref } from 'vue'
|
||||||
|
|
||||||
|
export type Column = {
|
||||||
|
prop: string
|
||||||
|
label: string
|
||||||
|
width?: string
|
||||||
|
align?: 'left' | 'center' | 'right'
|
||||||
|
}
|
||||||
|
|
||||||
|
type TableContext = {
|
||||||
|
columns: ReturnType<typeof ref<Column[]>>
|
||||||
|
addColumn: (column: Column) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
const key = Symbol('table')
|
||||||
|
|
||||||
|
export function useTable() {
|
||||||
|
const columns = ref<Column[]>([])
|
||||||
|
|
||||||
|
const addColumn = (column: Column) => {
|
||||||
|
columns.value.push(column)
|
||||||
|
}
|
||||||
|
|
||||||
|
provide(key, {
|
||||||
|
columns,
|
||||||
|
addColumn,
|
||||||
|
} as TableContext)
|
||||||
|
|
||||||
|
return {
|
||||||
|
columns,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useTableInject() {
|
||||||
|
const table = inject<TableContext>(key)
|
||||||
|
if (!table) {
|
||||||
|
throw new Error('useTable must be used within Table component')
|
||||||
|
}
|
||||||
|
return table
|
||||||
|
}
|
||||||
|
|
@ -2,20 +2,26 @@
|
||||||
<view class="flex flex-col p-[32rpx] bg-[#fff] mt-16rpx">
|
<view class="flex flex-col p-[32rpx] bg-[#fff] mt-16rpx">
|
||||||
<text class="text-[32rpx] font-semibold text-[#333]">院系设置</text>
|
<text class="text-[32rpx] font-semibold text-[#333]">院系设置</text>
|
||||||
|
|
||||||
<WXXTable :columns="columns" :tableData="tableData.slice(0, 4)" class="my-[24rpx]"></WXXTable>
|
<WXXTable :data="tableData.slice(0, 4)" class="my-[24rpx]">
|
||||||
<wd-button
|
<WXXTableCol prop="name" label="学院" width="30%"></WXXTableCol>
|
||||||
|
<WXXTableCol prop="major" label="所含专业" width="70%"></WXXTableCol>
|
||||||
|
</WXXTable>
|
||||||
|
<button
|
||||||
block
|
block
|
||||||
custom-class="mt-[24rpx] rounded-[8rpx]! bg-[#f8f8f8]! w-full text-[#303030]!"
|
class="mt-[24rpx] rounded-[8rpx]! bg-[#f8f8f8]! w-full text-[#303030]! text-[28rpx]! flex! items-center! justify-center! gap-[12rpx]!"
|
||||||
@click="handleMore"
|
@click="handleMore"
|
||||||
>
|
>
|
||||||
查看全部
|
查看全部
|
||||||
<wd-icon name="arrow-right"></wd-icon>
|
<view class="i-carbon-chevron-down rotate-270"></view>
|
||||||
</wd-button>
|
</button>
|
||||||
</view>
|
</view>
|
||||||
<MessageBox v-model:show="show" title="院系设置">
|
<MessageBox v-model:show="show" title="院系设置">
|
||||||
<template>
|
<template>
|
||||||
<scroll-view class="max-h-600rpx mb-[32rpx] overflow-y-auto" :scroll-y="true">
|
<scroll-view class="max-h-600rpx mb-[32rpx] overflow-y-auto" :scroll-y="true">
|
||||||
<WXXTable :columns="columns" :tableData="tableData"></WXXTable>
|
<WXXTable :data="tableData">
|
||||||
|
<WXXTableCol prop="name" label="学院" width="30%"></WXXTableCol>
|
||||||
|
<WXXTableCol prop="major" label="所含专业" width="70%"></WXXTableCol>
|
||||||
|
</WXXTable>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
</template>
|
</template>
|
||||||
</MessageBox>
|
</MessageBox>
|
||||||
|
|
@ -24,6 +30,7 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import MessageBox from '../../components/MessageBox.vue'
|
import MessageBox from '../../components/MessageBox.vue'
|
||||||
import WXXTable from '@/pages-sub/components/table/Table.vue'
|
import WXXTable from '@/pages-sub/components/table/Table.vue'
|
||||||
|
import WXXTableCol from '@/pages-sub/components/table/TableCol.vue'
|
||||||
import { getUniversityListByProvince } from '@/service/index/api'
|
import { getUniversityListByProvince } from '@/service/index/api'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
|
@ -49,10 +56,6 @@ watch(
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
const columns = [
|
|
||||||
{ name: '学院', key: 'name', width: '30%' },
|
|
||||||
{ name: '所含专业', key: 'major', width: '70%' },
|
|
||||||
]
|
|
||||||
const tableData = ref([])
|
const tableData = ref([])
|
||||||
const show = ref(false)
|
const show = ref(false)
|
||||||
let originTableData = []
|
let originTableData = []
|
||||||
|
|
|
||||||
|
|
@ -6,19 +6,27 @@
|
||||||
class="px-[24rpx] py-[8rpx] bg-[#f8f8f8] rounded-[8rpx] flex justify-between items-center text-[24rpx]"
|
class="px-[24rpx] py-[8rpx] bg-[#f8f8f8] rounded-[8rpx] flex justify-between items-center text-[24rpx]"
|
||||||
>
|
>
|
||||||
{{ year }}
|
{{ year }}
|
||||||
<wd-icon name="arrow-down" size="16rpx" custom-class="ml-[80rpx]"></wd-icon>
|
<view class="i-carbon-chevron-down rotate-270"></view>
|
||||||
</view>
|
</view>
|
||||||
<!-- <view
|
<!-- <view
|
||||||
@click="handleShow(2)"
|
@click="handleShow(2)"
|
||||||
class="px-[24rpx] py-[8rpx] bg-[#f8f8f8] rounded-[8rpx] flex justify-between items-center text-[24rpx]"
|
class="px-[24rpx] py-[8rpx] bg-[#f8f8f8] rounded-[8rpx] flex justify-between items-center text-[24rpx]"
|
||||||
>
|
>
|
||||||
{{ batche }}
|
{{ batche }}
|
||||||
<wd-icon name="arrow-down" size="16rpx" custom-class="ml-[80rpx]"></wd-icon>
|
<view class="i-carbon-chevron-down rotate-270"></view>
|
||||||
</view> -->
|
</view>
|
||||||
|
--->
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<scroll-view class="mt-[38rpx] flex-1 pb-safe">
|
<scroll-view class="mt-[38rpx] flex-1 pb-safe">
|
||||||
<WXXTable :columns="columns" :tableData="tableData"></WXXTable>
|
<WXXTable :data="tableData">
|
||||||
|
<WXXTableCol prop="year" label="年份" width="10%"></WXXTableCol>
|
||||||
|
<WXXTableCol prop="subject_name" label="院校/批次" width="19%"></WXXTableCol>
|
||||||
|
<WXXTableCol prop="second_subject" label="选考要求" width="17%"></WXXTableCol>
|
||||||
|
<WXXTableCol prop="enroll_num" label="录取数" width="13%"></WXXTableCol>
|
||||||
|
<WXXTableCol prop="score" label="分数" width="24%"></WXXTableCol>
|
||||||
|
<WXXTableCol prop="rank_min" label="最低位次" width="17%"></WXXTableCol>
|
||||||
|
</WXXTable>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
|
|
||||||
<wd-action-sheet v-model="show" title="">
|
<wd-action-sheet v-model="show" title="">
|
||||||
|
|
@ -35,6 +43,7 @@
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import WXXTable from '@/pages-sub/components/table/Table.vue'
|
import WXXTable from '@/pages-sub/components/table/Table.vue'
|
||||||
|
import WXXTableCol from '@/pages-sub/components/table/TableCol.vue'
|
||||||
import { getAdmissionMark } from '@/service/index/api'
|
import { getAdmissionMark } from '@/service/index/api'
|
||||||
import { useUserStore } from '@/store'
|
import { useUserStore } from '@/store'
|
||||||
import CustomPickerView from '@/pages-sub/components/CustomPickerView.vue'
|
import CustomPickerView from '@/pages-sub/components/CustomPickerView.vue'
|
||||||
|
|
@ -61,15 +70,6 @@ let pickType = 1
|
||||||
|
|
||||||
const tableData = ref([])
|
const tableData = ref([])
|
||||||
|
|
||||||
const columns = [
|
|
||||||
{ name: '年份', key: 'year', width: '10%' },
|
|
||||||
{ name: '院校/批次', key: 'subject_name', width: '19%' },
|
|
||||||
{ name: '选考要求', key: 'second_subject', width: '16%' },
|
|
||||||
{ name: '录取数', key: 'enroll_num', width: '13%' },
|
|
||||||
{ name: '分数', key: 'score', width: '24%' },
|
|
||||||
{ name: '最低位次', key: 'rank_min', width: '18%' },
|
|
||||||
]
|
|
||||||
|
|
||||||
let isFirst = true
|
let isFirst = true
|
||||||
watch(
|
watch(
|
||||||
() => props.id,
|
() => props.id,
|
||||||
|
|
|
||||||
|
|
@ -9,19 +9,25 @@
|
||||||
class="px-[24rpx] py-[8rpx] bg-[#f8f8f8] rounded-[8rpx] flex justify-between items-center text-[24rpx]"
|
class="px-[24rpx] py-[8rpx] bg-[#f8f8f8] rounded-[8rpx] flex justify-between items-center text-[24rpx]"
|
||||||
>
|
>
|
||||||
{{ year }}
|
{{ year }}
|
||||||
<wd-icon name="arrow-down" size="16rpx" custom-class="ml-[80rpx]"></wd-icon>
|
<view class="i-carbon-chevron-down rotate-270"></view>
|
||||||
</view>
|
</view>
|
||||||
<view
|
<view
|
||||||
@click="handleShow(2)"
|
@click="handleShow(2)"
|
||||||
class="px-[24rpx] py-[8rpx] bg-[#f8f8f8] rounded-[8rpx] flex justify-between items-center text-[24rpx]"
|
class="px-[24rpx] py-[8rpx] bg-[#f8f8f8] rounded-[8rpx] flex justify-between items-center text-[24rpx]"
|
||||||
>
|
>
|
||||||
{{ batche }}
|
{{ batche }}
|
||||||
<wd-icon name="arrow-down" size="16rpx" custom-class="ml-[80rpx]"></wd-icon>
|
<view class="i-carbon-chevron-down rotate-270"></view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<scroll-view class="mt-[38rpx] flex-1 pb-safe">
|
<scroll-view class="mt-[38rpx] flex-1 pb-safe">
|
||||||
<WXXTable :columns="columns" :tableData="tableData"></WXXTable>
|
<WXXTable :data="tableData">
|
||||||
|
<WXXTableCol prop="universityName" label="院校名称" width="25%"></WXXTableCol>
|
||||||
|
<WXXTableCol prop="major" label="招生专业" width="37%"></WXXTableCol>
|
||||||
|
<WXXTableCol prop="plancount" label="计划数" width="13%"></WXXTableCol>
|
||||||
|
<WXXTableCol prop="academic" label="学制" width="10%"></WXXTableCol>
|
||||||
|
<WXXTableCol prop="fee" label="学费" width="15%"></WXXTableCol>
|
||||||
|
</WXXTable>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
|
|
||||||
<wd-action-sheet v-model="show" title="">
|
<wd-action-sheet v-model="show" title="">
|
||||||
|
|
@ -38,6 +44,7 @@
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import WXXTable from '@/pages-sub/components/table/Table.vue'
|
import WXXTable from '@/pages-sub/components/table/Table.vue'
|
||||||
|
import WXXTableCol from '@/pages-sub/components/table/TableCol.vue'
|
||||||
import { getPlanProList } from '@/service/index/api'
|
import { getPlanProList } from '@/service/index/api'
|
||||||
import CustomPickerView from '@/pages-sub/components/CustomPickerView.vue'
|
import CustomPickerView from '@/pages-sub/components/CustomPickerView.vue'
|
||||||
import { useUserStore } from '@/store'
|
import { useUserStore } from '@/store'
|
||||||
|
|
@ -65,14 +72,6 @@ let pickType = 1
|
||||||
|
|
||||||
const tableData = ref([])
|
const tableData = ref([])
|
||||||
|
|
||||||
const columns = [
|
|
||||||
{ name: '院校名称', key: 'universityName', width: '25%' },
|
|
||||||
{ name: '招生专业', key: 'major', width: '37%' },
|
|
||||||
{ name: '计划数', key: 'plancount', width: '13%' },
|
|
||||||
{ name: '学制', key: 'academic', width: '10%' },
|
|
||||||
{ name: '学费', key: 'fee', width: '15%' },
|
|
||||||
]
|
|
||||||
|
|
||||||
let isFirst = true
|
let isFirst = true
|
||||||
watch(
|
watch(
|
||||||
() => props.id,
|
() => props.id,
|
||||||
|
|
@ -101,20 +100,22 @@ const getPlanProListData = async (newVal) => {
|
||||||
batchName: batche.value === '全部分类' ? '' : batche.value,
|
batchName: batche.value === '全部分类' ? '' : batche.value,
|
||||||
locationCode: userStore.userInfo.estimatedAchievement.provinceCode,
|
locationCode: userStore.userInfo.estimatedAchievement.provinceCode,
|
||||||
}).then((resp) => {
|
}).then((resp) => {
|
||||||
const _res = resp.result as {
|
if (resp.code === 200) {
|
||||||
batches: { batchName: string }[]
|
const _res = resp.result as {
|
||||||
yearsDtos: string[]
|
batches: { batchName: string }[]
|
||||||
plans: any[]
|
yearsDtos: string[]
|
||||||
}
|
plans: any[]
|
||||||
yearList.value = ['全部年份', ..._res.yearsDtos]
|
}
|
||||||
batches.value = ['全部分类', ..._res.batches.map((item) => item.batchName)]
|
yearList.value = ['全部年份', ..._res.yearsDtos]
|
||||||
tableData.value = _res.plans
|
batches.value = ['全部分类', ..._res.batches.map((item) => item.batchName)]
|
||||||
|
tableData.value = _res.plans
|
||||||
|
|
||||||
if (isFirst) {
|
if (isFirst) {
|
||||||
year.value = yearList.value[0]
|
year.value = yearList.value[0]
|
||||||
batche.value = batches.value[0]
|
batche.value = batches.value[0]
|
||||||
|
}
|
||||||
|
isFirst = false
|
||||||
}
|
}
|
||||||
isFirst = false
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,14 +6,14 @@
|
||||||
<text class="text-[22rpx] font-normal text-[#636363] my-[24rpx] line-clamp-3">
|
<text class="text-[22rpx] font-normal text-[#636363] my-[24rpx] line-clamp-3">
|
||||||
{{ subjectIntroduceList.join(',') }}
|
{{ subjectIntroduceList.join(',') }}
|
||||||
</text>
|
</text>
|
||||||
<wd-button
|
<button
|
||||||
block
|
block
|
||||||
custom-class="mt-[24rpx] rounded-[8rpx]! bg-[#f8f8f8]! w-full text-[#303030]!"
|
class="mt-[24rpx] rounded-[8rpx]! bg-[#f8f8f8]! w-full text-[#303030]! text-[28rpx]! flex! items-center! justify-center! gap-[12rpx]!"
|
||||||
@click="handleFullFun(1)"
|
@click="handleFullFun(1)"
|
||||||
>
|
>
|
||||||
查看全部
|
查看全部
|
||||||
<wd-icon name="arrow-right"></wd-icon>
|
<view class="i-carbon-chevron-down rotate-270"></view>
|
||||||
</wd-button>
|
</button>
|
||||||
</view>
|
</view>
|
||||||
<view
|
<view
|
||||||
class="flex flex-col p-[32rpx] bg-[#fff] mt-[16rpx]"
|
class="flex flex-col p-[32rpx] bg-[#fff] mt-[16rpx]"
|
||||||
|
|
@ -25,14 +25,14 @@
|
||||||
<text class="text-[22rpx] font-normal text-[#636363] my-[24rpx] line-clamp-3">
|
<text class="text-[22rpx] font-normal text-[#636363] my-[24rpx] line-clamp-3">
|
||||||
{{ assessmentSubjectList.join(',') }}
|
{{ assessmentSubjectList.join(',') }}
|
||||||
</text>
|
</text>
|
||||||
<wd-button
|
<button
|
||||||
block
|
block
|
||||||
custom-class="mt-[24rpx] rounded-[8rpx]! bg-[#f8f8f8]! w-full text-[#303030]!"
|
class="mt-[24rpx] rounded-[8rpx]! bg-[#f8f8f8]! w-full text-[#303030]! text-[28rpx]! flex! items-center! justify-center! gap-[12rpx]!"
|
||||||
@click="handleFullFun(2)"
|
@click="handleFullFun(2)"
|
||||||
>
|
>
|
||||||
查看全部
|
查看全部
|
||||||
<wd-icon name="arrow-right"></wd-icon>
|
<view class="i-carbon-chevron-down rotate-270"></view>
|
||||||
</wd-button>
|
</button>
|
||||||
</view>
|
</view>
|
||||||
<view class="flex flex-col p-[32rpx] bg-[#fff] mt-[16rpx]">
|
<view class="flex flex-col p-[32rpx] bg-[#fff] mt-[16rpx]">
|
||||||
<text class="text-[32rpx] font-semibold text-[#333]">
|
<text class="text-[32rpx] font-semibold text-[#333]">
|
||||||
|
|
@ -41,14 +41,14 @@
|
||||||
<text class="text-[22rpx] font-normal text-[#636363] my-[24rpx]">
|
<text class="text-[22rpx] font-normal text-[#636363] my-[24rpx]">
|
||||||
{{ featureSubjectList.join(',') }}
|
{{ featureSubjectList.join(',') }}
|
||||||
</text>
|
</text>
|
||||||
<wd-button
|
<button
|
||||||
block
|
block
|
||||||
custom-class="mt-[24rpx] rounded-[8rpx]! bg-[#f8f8f8]! w-full text-[#303030]!"
|
class="mt-[24rpx] rounded-[8rpx]! bg-[#f8f8f8]! w-full text-[#303030]! text-[28rpx]! flex! items-center! justify-center! gap-[12rpx]!"
|
||||||
@click="handleFullFun(3)"
|
@click="handleFullFun(3)"
|
||||||
>
|
>
|
||||||
查看全部
|
查看全部
|
||||||
<wd-icon name="arrow-right"></wd-icon>
|
<view class="i-carbon-chevron-down rotate-270"></view>
|
||||||
</wd-button>
|
</button>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<MessageBox v-model:show="show" :title="title">
|
<MessageBox v-model:show="show" :title="title">
|
||||||
|
|
|
||||||
|
|
@ -26,14 +26,14 @@
|
||||||
<view class="line-clamp-4 mt-[14rpx] text-[22rpx] text-[#636363]">
|
<view class="line-clamp-4 mt-[14rpx] text-[22rpx] text-[#636363]">
|
||||||
{{ universityResult?.detail }}
|
{{ universityResult?.detail }}
|
||||||
</view>
|
</view>
|
||||||
<wd-button
|
<button
|
||||||
block
|
block
|
||||||
custom-class="mt-[24rpx] rounded-[8rpx]! bg-[#f8f8f8]! w-full text-[#303030]!"
|
class="mt-[24rpx] rounded-[8rpx]! bg-[#f8f8f8]! w-full text-[#303030]! text-[28rpx]! flex! items-center! justify-center! gap-[16rpx]"
|
||||||
@click="show = true"
|
@click="show = true"
|
||||||
>
|
>
|
||||||
查看全部
|
查看全部
|
||||||
<wd-icon name="arrow-right"></wd-icon>
|
<view class="i-carbon-chevron-down rotate-270"></view>
|
||||||
</wd-button>
|
</button>
|
||||||
|
|
||||||
<MessageBox v-model:show="show" title="院校简介">
|
<MessageBox v-model:show="show" title="院校简介">
|
||||||
<template>
|
<template>
|
||||||
|
|
@ -47,7 +47,6 @@
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { UniversityResult } from '@/types/app-type'
|
import { UniversityResult } from '@/types/app-type'
|
||||||
import wdButton from 'wot-design-uni/components/wd-button/wd-button.vue'
|
|
||||||
import MessageBox from '../../components/MessageBox.vue'
|
import MessageBox from '../../components/MessageBox.vue'
|
||||||
|
|
||||||
defineProps({
|
defineProps({
|
||||||
|
|
|
||||||
|
|
@ -6,19 +6,26 @@
|
||||||
class="px-[24rpx] py-[8rpx] bg-[#f8f8f8] rounded-[8rpx] flex justify-between items-center text-[24rpx]"
|
class="px-[24rpx] py-[8rpx] bg-[#f8f8f8] rounded-[8rpx] flex justify-between items-center text-[24rpx]"
|
||||||
>
|
>
|
||||||
{{ year }}
|
{{ year }}
|
||||||
<wd-icon name="arrow-down" size="16rpx" custom-class="ml-[80rpx]"></wd-icon>
|
<view class="i-carbon-chevron-down"></view>
|
||||||
</view>
|
</view>
|
||||||
<view
|
<view
|
||||||
@click="handleShow(2)"
|
@click="handleShow(2)"
|
||||||
class="px-[24rpx] py-[8rpx] bg-[#f8f8f8] rounded-[8rpx] flex justify-between items-center text-[24rpx]"
|
class="px-[24rpx] py-[8rpx] bg-[#f8f8f8] rounded-[8rpx] flex justify-between items-center text-[24rpx]"
|
||||||
>
|
>
|
||||||
{{ provinceName || '请选择省份' }}
|
{{ provinceName || '请选择省份' }}
|
||||||
<wd-icon name="arrow-down" size="16rpx" custom-class="ml-[80rpx]"></wd-icon>
|
<view class="i-carbon-chevron-down"></view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<scroll-view class="mt-[38rpx] flex-1 pb-safe">
|
<scroll-view class="mt-[38rpx] flex-1 pb-safe">
|
||||||
<WXXTable :columns="columns" :tableData="tableData"></WXXTable>
|
<WXXTable :data="tableData">
|
||||||
|
<WXXTableCol prop="years" label="年份" width="10%"></WXXTableCol>
|
||||||
|
<WXXTableCol prop="batchName" label="院校/批次" width="19%"></WXXTableCol>
|
||||||
|
<WXXTableCol prop="selectsubject" label="选考要求" width="16%"></WXXTableCol>
|
||||||
|
<WXXTableCol prop="plancount" label="录取数" width="13%"></WXXTableCol>
|
||||||
|
<WXXTableCol prop="lowscore" label="分数" width="24%"></WXXTableCol>
|
||||||
|
<WXXTableCol prop="lowscorerank" label="最低位次" width="18%"></WXXTableCol>
|
||||||
|
</WXXTable>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
|
|
||||||
<wd-action-sheet v-model="show" title="">
|
<wd-action-sheet v-model="show" title="">
|
||||||
|
|
@ -45,6 +52,7 @@
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import WXXTable from '@/pages-sub/components/table/Table.vue'
|
import WXXTable from '@/pages-sub/components/table/Table.vue'
|
||||||
|
import WXXTableCol from '@/pages-sub/components/table/TableCol.vue'
|
||||||
import { getPlanProList } from '@/service/index/api'
|
import { getPlanProList } from '@/service/index/api'
|
||||||
import { useUserStore } from '@/store'
|
import { useUserStore } from '@/store'
|
||||||
import Region from '@/pages-sub/home/components/Region.vue'
|
import Region from '@/pages-sub/home/components/Region.vue'
|
||||||
|
|
@ -71,15 +79,6 @@ let pickType = 1
|
||||||
|
|
||||||
const tableData = ref([])
|
const tableData = ref([])
|
||||||
|
|
||||||
const columns = [
|
|
||||||
{ name: '年份', key: 'years', width: '10%' },
|
|
||||||
{ name: '院校/批次', key: 'batchName', width: '19%' },
|
|
||||||
{ name: '选考要求', key: 'selectsubject', width: '16%' },
|
|
||||||
{ name: '录取数', key: 'plancount', width: '13%' },
|
|
||||||
{ name: '分数', key: 'lowscore', width: '24%' },
|
|
||||||
{ name: '最低位次', key: 'lowscorerank', width: '18%' },
|
|
||||||
]
|
|
||||||
|
|
||||||
let isFirst = true
|
let isFirst = true
|
||||||
watch(
|
watch(
|
||||||
() => props.id,
|
() => props.id,
|
||||||
|
|
@ -108,19 +107,21 @@ const getPlanProListData = async (newVal) => {
|
||||||
batchName: '',
|
batchName: '',
|
||||||
locationCode: userStore.userInfo.estimatedAchievement.provinceCode,
|
locationCode: userStore.userInfo.estimatedAchievement.provinceCode,
|
||||||
}).then((resp) => {
|
}).then((resp) => {
|
||||||
const _res = resp.result as {
|
if (resp.code === 200) {
|
||||||
batches: { batchName: string }[]
|
const _res = resp.result as {
|
||||||
yearsDtos: string[]
|
batches: { batchName: string }[]
|
||||||
plans: any[]
|
yearsDtos: string[]
|
||||||
}
|
plans: any[]
|
||||||
yearList.value = ['全部年份', ..._res.yearsDtos]
|
}
|
||||||
|
yearList.value = ['全部年份', ..._res.yearsDtos]
|
||||||
|
|
||||||
tableData.value = _res.plans
|
// tableData.value = _res.plans
|
||||||
|
|
||||||
if (isFirst) {
|
if (isFirst) {
|
||||||
year.value = yearList.value[0]
|
year.value = yearList.value[0]
|
||||||
|
}
|
||||||
|
isFirst = false
|
||||||
}
|
}
|
||||||
isFirst = false
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@
|
||||||
@open="handleOpenSubMenu(item.id)"
|
@open="handleOpenSubMenu(item.id)"
|
||||||
custom-class="flex items-center"
|
custom-class="flex items-center"
|
||||||
>
|
>
|
||||||
<view class="pt-[32rpx]">
|
<view class="">
|
||||||
<Region v-if="currentMenu === 1" @changeName="handleRegionChange" />
|
<Region v-if="currentMenu === 1" @changeName="handleRegionChange" />
|
||||||
<Nature v-if="currentMenu === 2" @changeName="handleNatureChange" />
|
<Nature v-if="currentMenu === 2" @changeName="handleNatureChange" />
|
||||||
<UniType v-if="currentMenu === 3" @changeName="handleUniTypeChange" />
|
<UniType v-if="currentMenu === 3" @changeName="handleUniTypeChange" />
|
||||||
|
|
|
||||||
|
|
@ -41,14 +41,11 @@
|
||||||
{{ universityBaseInfo?.universityResult.features.slice(0, 4).join('/ ') }}
|
{{ universityBaseInfo?.universityResult.features.slice(0, 4).join('/ ') }}
|
||||||
</text>
|
</text>
|
||||||
</view>
|
</view>
|
||||||
<wd-button
|
<button class="collect-btn" plain @click="handleStar">
|
||||||
:icon="startFlag ? 'star-filled' : 'star'"
|
<view class="i-carbon-star-filled" v-if="startFlag"></view>
|
||||||
custom-class="collect-btn"
|
<view class="i-carbon-star" v-else></view>
|
||||||
plain
|
|
||||||
@click="handleStar"
|
|
||||||
>
|
|
||||||
收藏
|
收藏
|
||||||
</wd-button>
|
</button>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="card-swiper mb-[32rpx]">
|
<view class="card-swiper mb-[32rpx]">
|
||||||
|
|
@ -199,6 +196,8 @@ const handleStar = () => {
|
||||||
display: flex !important;
|
display: flex !important;
|
||||||
justify-content: space-between !important;
|
justify-content: space-between !important;
|
||||||
align-items: center !important;
|
align-items: center !important;
|
||||||
|
|
||||||
|
font-size: 24rpx !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.wd-button__icon) {
|
:deep(.wd-button__icon) {
|
||||||
|
|
|
||||||
|
|
@ -19,9 +19,24 @@
|
||||||
</view>
|
</view>
|
||||||
<view class="flex-1 pb-[24rpx] h-[50vh] overflow-y-auto">
|
<view class="flex-1 pb-[24rpx] h-[50vh] overflow-y-auto">
|
||||||
<Phase v-show="currentMenu === 1" />
|
<Phase v-show="currentMenu === 1" />
|
||||||
<Region class="custom-wrapper" v-show="currentMenu === 2" />
|
<Region
|
||||||
<UniType class="custom-wrapper" v-show="currentMenu === 3" />
|
width="240rpx"
|
||||||
<Nature class="custom-wrapper" v-show="currentMenu === 4" />
|
height="60rpx"
|
||||||
|
class="justify-center!"
|
||||||
|
v-show="currentMenu === 2"
|
||||||
|
/>
|
||||||
|
<UniType
|
||||||
|
width="240rpx"
|
||||||
|
height="60rpx"
|
||||||
|
class="justify-center!"
|
||||||
|
v-show="currentMenu === 3"
|
||||||
|
/>
|
||||||
|
<Nature
|
||||||
|
width="240rpx"
|
||||||
|
height="60rpx"
|
||||||
|
class="justify-center!"
|
||||||
|
v-show="currentMenu === 4"
|
||||||
|
/>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="pt-[32rpx] px-[32rpx] wei-xin-pt box-shadow">
|
<view class="pt-[32rpx] px-[32rpx] wei-xin-pt box-shadow">
|
||||||
|
|
@ -32,21 +47,22 @@
|
||||||
:key="item"
|
:key="item"
|
||||||
>
|
>
|
||||||
<text class="text-[#303030] text-[24rpx] font-medium mr-[16rpx]">中外合作</text>
|
<text class="text-[#303030] text-[24rpx] font-medium mr-[16rpx]">中外合作</text>
|
||||||
<wd-icon name="close-outline" size="24rpx" color="#cbcbcb"></wd-icon>
|
<view class="i-carbon-close-filled"></view>
|
||||||
|
|
||||||
</view>
|
</view>
|
||||||
</view> -->
|
</view> -->
|
||||||
<view class="flex items-center">
|
<view class="flex items-center">
|
||||||
<wd-button
|
<button
|
||||||
plain
|
plain
|
||||||
custom-class="border-[#f5f5f5]! px-[134rpx]! py-[26rpx]! bg-[#f5f5f5]! rounded-[8rpx]! text-[#1580FF]! text-[32rpx]! font-normal! mr-[22rpx]"
|
class="border-[#f5f5f5]! flex-auto bg-[#f5f5f5]! rounded-[8rpx]! text-[#1580FF]! text-[32rpx]! font-normal! mr-[22rpx]"
|
||||||
>
|
>
|
||||||
清空
|
清空
|
||||||
</wd-button>
|
</button>
|
||||||
<wd-button
|
<button
|
||||||
custom-class="border-[#1580FF]! px-[134rpx]! py-[26rpx]! bg-[#1580FF]! rounded-[8rpx]! text-[#fff]! text-[32rpx]! font-normal!"
|
class="border-[#1580FF]! flex-auto bg-[#1580FF]! rounded-[8rpx]! text-[#fff]! text-[32rpx]! font-normal!"
|
||||||
>
|
>
|
||||||
查看结果
|
查看结果
|
||||||
</wd-button>
|
</button>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
@ -106,9 +122,10 @@ const changeMenu = (item: { id: number; name: string }) => {
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.checkbox {
|
.large-checkbox {
|
||||||
width: 240rpx !important;
|
:deep(.custom-checkbox) {
|
||||||
height: 60rpx !important;
|
--checkbox-width: 240rpx;
|
||||||
background: #f7f8fa !important;
|
--checkbox-height: 60rpx;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -5,12 +5,11 @@
|
||||||
<text class="text-[36rpx] text-[#303030] font-bold text-center">
|
<text class="text-[36rpx] text-[#303030] font-bold text-center">
|
||||||
{{ title }}
|
{{ title }}
|
||||||
</text>
|
</text>
|
||||||
<wd-icon
|
|
||||||
name="close"
|
<view
|
||||||
size="40rpx"
|
class="i-carbon-close absolute right-[40rpx] text-[40rpx]"
|
||||||
custom-class="absolute right-[40rpx]"
|
|
||||||
@click="emits('update:show', false)"
|
@click="emits('update:show', false)"
|
||||||
></wd-icon>
|
></view>
|
||||||
</view>
|
</view>
|
||||||
<view class="min-h-[200rpx] h-max-content overflow-y-auto px-[32rpx]">
|
<view class="min-h-[200rpx] h-max-content overflow-y-auto px-[32rpx]">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
<!-- 大学甄别 -->
|
<!-- 大学甄别 -->
|
||||||
|
|
||||||
<template>
|
<template></template>
|
||||||
<text>大学甄别</text>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup></script>
|
<script lang="ts" setup></script>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,171 @@
|
||||||
|
<route lang="json5" type="page">
|
||||||
|
{
|
||||||
|
layout: 'page',
|
||||||
|
style: {
|
||||||
|
navigationStyle: 'custom',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</route>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<text>查扩缩招</text>
|
<view class="flex flex-col h-screen">
|
||||||
|
<view class="relative">
|
||||||
|
<Navbar
|
||||||
|
safeAreaInsetTop
|
||||||
|
bg-color="transparent"
|
||||||
|
:bordered="false"
|
||||||
|
left-arrow
|
||||||
|
title="查扩缩招"
|
||||||
|
@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.searchNature || '层次'"
|
||||||
|
custom-class="flex items-center"
|
||||||
|
>
|
||||||
|
<Nature @changeName="handleNatureChange" />
|
||||||
|
</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>
|
||||||
|
|
||||||
|
<view class="px-32rpx">
|
||||||
|
<view class="flex items-center justify-between input-wrapper-class">
|
||||||
|
<input
|
||||||
|
v-model="searchParams.Score"
|
||||||
|
type="number"
|
||||||
|
placeholder="请输入你的高考分数"
|
||||||
|
confirm-type="done"
|
||||||
|
input-mode="numeric"
|
||||||
|
class="flex-auto"
|
||||||
|
/>
|
||||||
|
<view class="text-[#1580FF] text-[24rpx] search-text" @click="handleConfirm">查询</view>
|
||||||
|
</view>
|
||||||
|
<view class="text-[#636363] text-[20rpx] mt-[24rpx]">分数范围:{{ betweenScores }}</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="bg-[#F8F8F8] h-[16rpx] mt-[40rpx]"></view>
|
||||||
|
</view>
|
||||||
</template>
|
</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 Nature from '@/pages-sub/home/components/Nature.vue'
|
||||||
|
|
||||||
|
import { getBatchList } from '@/service/index/api'
|
||||||
|
|
||||||
|
const userStore = useUserStore()
|
||||||
|
|
||||||
|
const searchParams = ref({
|
||||||
|
locationCode: userStore.userInfo.estimatedAchievement.provinceCode || '370000',
|
||||||
|
locationName: userStore.userInfo.estimatedAchievement.provinceName || '山东省',
|
||||||
|
type: '',
|
||||||
|
searchNature: '',
|
||||||
|
Score: '',
|
||||||
|
})
|
||||||
|
|
||||||
|
const handleConfirm = () => {
|
||||||
|
getBatchListData()
|
||||||
|
}
|
||||||
|
|
||||||
|
const betweenScores = ref('')
|
||||||
|
|
||||||
|
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 handleNatureChange = (val) => {}
|
||||||
|
|
||||||
|
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: '',
|
||||||
|
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';
|
||||||
|
|
||||||
|
.input-wrapper-class {
|
||||||
|
border-radius: 8rpx;
|
||||||
|
border: 2rpx solid #ededed;
|
||||||
|
padding: 10rpx 24rpx;
|
||||||
|
margin-top: 48rpx;
|
||||||
|
|
||||||
|
.search-text {
|
||||||
|
border-left: 2rpx solid #ededed;
|
||||||
|
padding-left: 24rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -86,14 +86,14 @@
|
||||||
</Checkbox>
|
</Checkbox>
|
||||||
</CheckboxGroup>
|
</CheckboxGroup>
|
||||||
</view>
|
</view>
|
||||||
<wd-button
|
<button
|
||||||
block
|
block
|
||||||
custom-class="mt-auto mb-[32rpx] rounded-[8rpx]! bg-[#1580FF]! mx-[32rpx]"
|
class="mt-auto mb-[32rpx] rounded-[8rpx]! bg-[#1580FF]! mx-[32rpx]! text-[32rpx]! text-[#fff]! font-normal"
|
||||||
@click="saveScore"
|
@click="saveScore"
|
||||||
:disabled="btnFlag < 3"
|
:disabled="btnFlag < 3"
|
||||||
>
|
>
|
||||||
保存
|
保存
|
||||||
</wd-button>
|
</button>
|
||||||
<view class="bg-white pb-safe" hover-class="none"></view>
|
<view class="bg-white pb-safe" hover-class="none"></view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
bg-color="transparent"
|
bg-color="transparent"
|
||||||
:bordered="false"
|
:bordered="false"
|
||||||
left-arrow
|
left-arrow
|
||||||
:title="`近4年批次线(${userStore.userInfo.estimatedAchievement.provinceName})`"
|
:title="`近4年批次线(${searchParams.locationName})`"
|
||||||
@click-left="navigatorBack"
|
@click-left="navigatorBack"
|
||||||
/>
|
/>
|
||||||
<view class="custom-background h-[200rpx] w-full absolute top-0 left-0 z-[-1]"></view>
|
<view class="custom-background h-[200rpx] w-full absolute top-0 left-0 z-[-1]"></view>
|
||||||
|
|
@ -55,11 +55,13 @@
|
||||||
/>
|
/>
|
||||||
</drop-menu-item>
|
</drop-menu-item>
|
||||||
</drop-menu>
|
</drop-menu>
|
||||||
<WXXTable
|
<WXXTable :data="lineList" class="px-[32rpx] mt-[16rpx] pb-safe">
|
||||||
:columns="columns"
|
<WXXTableCol prop="province_name" label="地区" width="14%"></WXXTableCol>
|
||||||
:tableData="lineList"
|
<WXXTableCol prop="year" label="年份" width="23%"></WXXTableCol>
|
||||||
class="px-[32rpx] mt-[16rpx] pb-safe"
|
<WXXTableCol prop="subject_name" label="类别" width="23%"></WXXTableCol>
|
||||||
></WXXTable>
|
<WXXTableCol prop="batch_name" label="批次" width="23%"></WXXTableCol>
|
||||||
|
<WXXTableCol prop="score" label="分数线" width="17%"></WXXTableCol>
|
||||||
|
</WXXTable>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -73,14 +75,15 @@ import UniType from '@/pages-sub/home/components/UniType.vue'
|
||||||
|
|
||||||
import CheckGroup from '@/pages-sub/components/check-group/CheckGroup.vue'
|
import CheckGroup from '@/pages-sub/components/check-group/CheckGroup.vue'
|
||||||
import WXXTable from '@/pages-sub/components/table/Table.vue'
|
import WXXTable from '@/pages-sub/components/table/Table.vue'
|
||||||
|
import WXXTableCol from '@/pages-sub/components/table/TableCol.vue'
|
||||||
|
|
||||||
import { getBatchList } from '@/service/index/api'
|
import { getBatchList } from '@/service/index/api'
|
||||||
|
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
|
|
||||||
const searchParams = ref({
|
const searchParams = ref({
|
||||||
locationCode: userStore.userInfo.estimatedAchievement.provinceCode,
|
locationCode: userStore.userInfo.estimatedAchievement.provinceCode || '370000',
|
||||||
locationName: userStore.userInfo.estimatedAchievement.provinceName,
|
locationName: userStore.userInfo.estimatedAchievement.provinceName || '山东省',
|
||||||
year: '',
|
year: '',
|
||||||
type: '',
|
type: '',
|
||||||
})
|
})
|
||||||
|
|
@ -117,14 +120,6 @@ const handleYearChange = (val) => {
|
||||||
getBatchListData()
|
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 = {
|
type LineItem = {
|
||||||
batch_id: number
|
batch_id: number
|
||||||
batch_name: string
|
batch_name: string
|
||||||
|
|
|
||||||
|
|
@ -4,14 +4,14 @@
|
||||||
<text class="text-[22rpx] font-normal text-[#636363] my-[24rpx] line-clamp-3">
|
<text class="text-[22rpx] font-normal text-[#636363] my-[24rpx] line-clamp-3">
|
||||||
{{ careerInfo.jobs || '暂无' }}
|
{{ careerInfo.jobs || '暂无' }}
|
||||||
</text>
|
</text>
|
||||||
<wd-button
|
<button
|
||||||
block
|
block
|
||||||
custom-class="mt-[24rpx] rounded-[8rpx]! bg-[#f8f8f8]! w-full text-[#303030]!"
|
class="mt-[24rpx] rounded-[8rpx]! bg-[#f8f8f8]! w-full text-[#303030]! text-[28rpx]! flex! items-center! justify-center! gap-[16rpx]"
|
||||||
@click="handleFullFun(1)"
|
@click="handleFullFun(1)"
|
||||||
>
|
>
|
||||||
查看全部
|
查看全部
|
||||||
<wd-icon name="arrow-right"></wd-icon>
|
<view class="i-carbon-chevron-down rotate-270"></view>
|
||||||
</wd-button>
|
</button>
|
||||||
</view>
|
</view>
|
||||||
<view class="h-[16rpx] bg-[#f8f8f8]"></view>
|
<view class="h-[16rpx] bg-[#f8f8f8]"></view>
|
||||||
<view class="flex flex-col py-[32rpx] px-[24rpx] bg-[#fff]">
|
<view class="flex flex-col py-[32rpx] px-[24rpx] bg-[#fff]">
|
||||||
|
|
@ -19,14 +19,14 @@
|
||||||
<text class="text-[22rpx] font-normal text-[#636363] my-[24rpx] line-clamp-3">
|
<text class="text-[22rpx] font-normal text-[#636363] my-[24rpx] line-clamp-3">
|
||||||
{{ careerInfo.profession || '暂无' }}
|
{{ careerInfo.profession || '暂无' }}
|
||||||
</text>
|
</text>
|
||||||
<wd-button
|
<button
|
||||||
block
|
block
|
||||||
custom-class="mt-[24rpx] rounded-[8rpx]! bg-[#f8f8f8]! w-full text-[#303030]!"
|
class="mt-[24rpx] rounded-[8rpx]! bg-[#f8f8f8]! w-full text-[#303030]! text-[28rpx]! flex! items-center! justify-center! gap-[16rpx]"
|
||||||
@click="handleFullFun(2)"
|
@click="handleFullFun(2)"
|
||||||
>
|
>
|
||||||
查看全部
|
查看全部
|
||||||
<wd-icon name="arrow-right"></wd-icon>
|
<view class="i-carbon-chevron-down rotate-270"></view>
|
||||||
</wd-button>
|
</button>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="h-[16rpx] bg-[#f8f8f8]"></view>
|
<view class="h-[16rpx] bg-[#f8f8f8]"></view>
|
||||||
|
|
|
||||||
|
|
@ -5,14 +5,14 @@
|
||||||
<text class="text-[22rpx] font-normal text-[#636363] my-[24rpx] line-clamp-3">
|
<text class="text-[22rpx] font-normal text-[#636363] my-[24rpx] line-clamp-3">
|
||||||
{{ zyjx || '暂无' }}
|
{{ zyjx || '暂无' }}
|
||||||
</text>
|
</text>
|
||||||
<wd-button
|
<button
|
||||||
block
|
block
|
||||||
custom-class="mt-[24rpx] rounded-[8rpx]! bg-[#f8f8f8]! w-full text-[#303030]!"
|
class="mt-[24rpx] rounded-[8rpx]! bg-[#f8f8f8]! w-full text-[#303030]! text-[28rpx]! flex! items-center! justify-center! gap-[16rpx]"
|
||||||
@click="handleFullFun(1)"
|
@click="handleFullFun(1)"
|
||||||
>
|
>
|
||||||
查看全部
|
查看全部
|
||||||
<wd-icon name="arrow-right"></wd-icon>
|
<view class="i-carbon-chevron-down rotate-270"></view>
|
||||||
</wd-button>
|
</button>
|
||||||
</view>
|
</view>
|
||||||
<view class="h-[16rpx] bg-[#f8f8f8]"></view>
|
<view class="h-[16rpx] bg-[#f8f8f8]"></view>
|
||||||
<view class="flex flex-col py-[32rpx] px-[24rpx] bg-[#fff]">
|
<view class="flex flex-col py-[32rpx] px-[24rpx] bg-[#fff]">
|
||||||
|
|
@ -21,33 +21,34 @@
|
||||||
<text class="text-[22rpx] font-normal text-[#636363] my-[24rpx] line-clamp-3">
|
<text class="text-[22rpx] font-normal text-[#636363] my-[24rpx] line-clamp-3">
|
||||||
{{ kyfx.map((item) => item.zymc).join(',') || '暂无' }}
|
{{ kyfx.map((item) => item.zymc).join(',') || '暂无' }}
|
||||||
</text>
|
</text>
|
||||||
<wd-button
|
|
||||||
|
<button
|
||||||
block
|
block
|
||||||
custom-class="mt-[24rpx] rounded-[8rpx]! bg-[#f8f8f8]! w-full text-[#303030]!"
|
class="mt-[24rpx] rounded-[8rpx]! bg-[#f8f8f8]! w-full text-[#303030]! text-[28rpx]! flex! items-center! justify-center! gap-[16rpx]"
|
||||||
@click="handleFullFun(2)"
|
@click="handleFullFun(2)"
|
||||||
>
|
>
|
||||||
查看全部
|
查看全部
|
||||||
<wd-icon name="arrow-right"></wd-icon>
|
<view class="i-carbon-chevron-down rotate-270"></view>
|
||||||
</wd-button>
|
</button>
|
||||||
</view>
|
</view>
|
||||||
<view class="h-[16rpx] bg-[#f8f8f8]"></view>
|
<view class="h-[16rpx] bg-[#f8f8f8]"></view>
|
||||||
<view class="flex flex-col py-[32rpx] px-[24rpx] bg-[#fff]">
|
<view class="flex flex-col py-[32rpx] px-[24rpx] bg-[#fff]">
|
||||||
<text class="text-[32rpx] font-semibold text-[#333]">课程列表</text>
|
<text class="text-[32rpx] font-semibold text-[#333]">课程列表</text>
|
||||||
<view class="my-[24rpx]">
|
<view class="my-[24rpx]">
|
||||||
<WXXTable
|
<WXXTable :data="courseInfo.slice(0, 4)" class="my-[24rpx]">
|
||||||
:columns="columns"
|
<WXXTableCol prop="kcmc" label="课程名称" width="50%"></WXXTableCol>
|
||||||
:tableData="courseInfo.slice(0, 4)"
|
<WXXTableCol prop="difficulty" label="课程难易度" width="25%"></WXXTableCol>
|
||||||
class="my-[24rpx]"
|
<WXXTableCol prop="practicality" label="课程实用度" width="25%"></WXXTableCol>
|
||||||
></WXXTable>
|
</WXXTable>
|
||||||
</view>
|
</view>
|
||||||
<wd-button
|
<button
|
||||||
block
|
block
|
||||||
custom-class="mt-[24rpx] rounded-[8rpx]! bg-[#f8f8f8]! w-full text-[#303030]!"
|
class="mt-[24rpx] rounded-[8rpx]! bg-[#f8f8f8]! w-full text-[#303030]! text-[28rpx]! flex! items-center! justify-center! gap-[16rpx]"
|
||||||
@click="handleFullFun(3)"
|
@click="handleFullFun(3)"
|
||||||
>
|
>
|
||||||
查看全部
|
查看全部
|
||||||
<wd-icon name="arrow-right"></wd-icon>
|
<view class="i-carbon-chevron-down rotate-270"></view>
|
||||||
</wd-button>
|
</button>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<MessageBox v-model:show="show" :title="title">
|
<MessageBox v-model:show="show" :title="title">
|
||||||
|
|
@ -55,12 +56,14 @@
|
||||||
<view class="text-[22rpx] text-[#636363] max-h-600rpx mb-[32rpx]" v-show="showType !== 3">
|
<view class="text-[22rpx] text-[#636363] max-h-600rpx mb-[32rpx]" v-show="showType !== 3">
|
||||||
{{ innerContent }}
|
{{ innerContent }}
|
||||||
</view>
|
</view>
|
||||||
<WXXTable
|
<scroll-view class="max-h-600rpx mb-[32rpx] overflow-y-auto" :scroll-y="true">
|
||||||
:columns="columns"
|
<WXXTable :data="courseInfo" class="my-[24rpx]" v-show="showType === 3">
|
||||||
:tableData="courseInfo"
|
>
|
||||||
class="my-[24rpx]"
|
<WXXTableCol prop="kcmc" label="课程名称" width="50%"></WXXTableCol>
|
||||||
v-show="showType === 3"
|
<WXXTableCol prop="difficulty" label="课程难易度" width="25%"></WXXTableCol>
|
||||||
></WXXTable>
|
<WXXTableCol prop="practicality" label="课程实用度" width="25%"></WXXTableCol>
|
||||||
|
</WXXTable>
|
||||||
|
</scroll-view>
|
||||||
</template>
|
</template>
|
||||||
</MessageBox>
|
</MessageBox>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -68,6 +71,7 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import MessageBox from '@/pages-sub/home/components/MessageBox.vue'
|
import MessageBox from '@/pages-sub/home/components/MessageBox.vue'
|
||||||
import WXXTable from '@/pages-sub/components/table/Table.vue'
|
import WXXTable from '@/pages-sub/components/table/Table.vue'
|
||||||
|
import WXXTableCol from '@/pages-sub/components/table/TableCol.vue'
|
||||||
import { getMajorCourse } from '@/service/index/api'
|
import { getMajorCourse } from '@/service/index/api'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
|
@ -85,12 +89,6 @@ const props = defineProps({
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const columns = [
|
|
||||||
{ name: '课程名称', key: 'kcmc', width: '50%' },
|
|
||||||
{ name: '课程难易度', key: 'difficulty', width: '25%' },
|
|
||||||
{ name: '课程实用度', key: 'practicality', width: '25%' },
|
|
||||||
]
|
|
||||||
|
|
||||||
const courseInfo = ref<any[]>([])
|
const courseInfo = ref<any[]>([])
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,11 @@
|
||||||
>
|
>
|
||||||
{{ item.childMajors.length }}
|
{{ item.childMajors.length }}
|
||||||
</text>
|
</text>
|
||||||
<wd-icon name="arrow-up" size="16rpx" v-if="expanded" color="#1580FF"></wd-icon>
|
<view
|
||||||
<wd-icon name="arrow-down" size="16rpx" v-else></wd-icon>
|
class="i-carbon-chevron-down rotate-180 text-[16rpx] text-[#1580FF]"
|
||||||
|
v-if="expanded"
|
||||||
|
></view>
|
||||||
|
<view class="i-carbon-chevron-down text-[16rpx]" v-else></view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@
|
||||||
class="px-[24rpx] py-[8rpx] bg-[#f8f8f8] rounded-[8rpx] flex justify-between items-center text-[24rpx] w-[144rpx] mt-[30rpx]"
|
class="px-[24rpx] py-[8rpx] bg-[#f8f8f8] rounded-[8rpx] flex justify-between items-center text-[24rpx] w-[144rpx] mt-[30rpx]"
|
||||||
>
|
>
|
||||||
{{ provinceName || '不限' }}
|
{{ provinceName || '不限' }}
|
||||||
<wd-icon name="arrow-down" size="16rpx" custom-class="ml-[80rpx]"></wd-icon>
|
<view class="i-carbon-chevron-down text-[16rpx]"></view>
|
||||||
</view>
|
</view>
|
||||||
<scroll-view :scroll-x="true" class="">
|
<scroll-view :scroll-x="true" class="">
|
||||||
<view
|
<view
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
</route>
|
</route>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<view class="pb-safe flex flex-col h-screen">
|
<view class="flex flex-col h-screen">
|
||||||
<view class="relative">
|
<view class="relative">
|
||||||
<Navbar
|
<Navbar
|
||||||
safeAreaInsetTop
|
safeAreaInsetTop
|
||||||
|
|
|
||||||
|
|
@ -191,7 +191,11 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "home/expand/index",
|
"path": "home/expand/index",
|
||||||
"type": "page"
|
"type": "page",
|
||||||
|
"layout": "page",
|
||||||
|
"style": {
|
||||||
|
"navigationStyle": "custom"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "home/inputScore/index",
|
"path": "home/inputScore/index",
|
||||||
|
|
@ -275,6 +279,20 @@
|
||||||
{
|
{
|
||||||
"path": "index",
|
"path": "index",
|
||||||
"type": "page"
|
"type": "page"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "rank/index",
|
||||||
|
"type": "page",
|
||||||
|
"layout": "page",
|
||||||
|
"style": {
|
||||||
|
"navigationStyle": "custom"
|
||||||
|
},
|
||||||
|
"usingComponents": {
|
||||||
|
"LEchart": "../uni_modules/lime-echart/components/l-echart/l-echart"
|
||||||
|
},
|
||||||
|
"componentPlaceholder": {
|
||||||
|
"LEchart": "view"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<scroll-view class="" :scroll-y="true">
|
<scroll-view class="" :scroll-y="true">
|
||||||
<view class="gradient-background relative">
|
<view class="gradient-background relative">
|
||||||
<Navbar safeAreaInsetTop bg-color="transparent" :bordered="false">
|
<Navbar safeAreaInsetTop bg-color="transparent" placeholder :bordered="false">
|
||||||
<template #left>
|
<template #left>
|
||||||
<navigator open-type="navigate" class="left-icon" url="/pages-sub/home/city/index">
|
<navigator open-type="navigate" class="left-icon" url="/pages-sub/home/city/index">
|
||||||
<text
|
<text
|
||||||
|
|
|
||||||
|
|
@ -182,3 +182,12 @@ export const getProfessionInfo = (params: { id: string }) => {
|
||||||
export const getBatchList = (params: { locationCode: string; year: string; type: string }) => {
|
export const getBatchList = (params: { locationCode: string; year: string; type: string }) => {
|
||||||
return http.get('/api/zhiYuan/batchList', params)
|
return http.get('/api/zhiYuan/batchList', params)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const getScoreSection = (params: {
|
||||||
|
locationCode: string
|
||||||
|
year: string
|
||||||
|
type: string
|
||||||
|
Score: string
|
||||||
|
}) => {
|
||||||
|
return http.get('/api/ScoreSection/scoreSection/V2', params)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,8 @@ interface NavigateToOptions {
|
||||||
"/pages-sub/home/rank/index" |
|
"/pages-sub/home/rank/index" |
|
||||||
"/pages-sub/home/schoolRank/index" |
|
"/pages-sub/home/schoolRank/index" |
|
||||||
"/login-sub/index" |
|
"/login-sub/index" |
|
||||||
"/pages-evaluation-sub/index";
|
"/pages-evaluation-sub/index" |
|
||||||
|
"/pages-evaluation-sub/rank/index";
|
||||||
}
|
}
|
||||||
interface RedirectToOptions extends NavigateToOptions {}
|
interface RedirectToOptions extends NavigateToOptions {}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
import { CustomRequestOptions } from '@/interceptors/request'
|
import { CustomRequestOptions } from '@/interceptors/request'
|
||||||
import { staticBaseUrl, baseUrl } from '@/utils/index'
|
import { staticBaseUrl, baseUrl } from '@/utils/index'
|
||||||
|
import { useUserStore } from '@/store'
|
||||||
|
|
||||||
|
const userStore = useUserStore()
|
||||||
|
|
||||||
export const http = <T>(options: CustomRequestOptions) => {
|
export const http = <T>(options: CustomRequestOptions) => {
|
||||||
// 1. 返回 Promise 对象
|
// 1. 返回 Promise 对象
|
||||||
|
|
@ -14,13 +17,15 @@ export const http = <T>(options: CustomRequestOptions) => {
|
||||||
// 响应成功
|
// 响应成功
|
||||||
success(res) {
|
success(res) {
|
||||||
// 状态码 2xx,参考 axios 的设计
|
// 状态码 2xx,参考 axios 的设计
|
||||||
if (res.statusCode >= 200 && res.statusCode < 300) {
|
if ((res.data as IResData<T>).code === 401) {
|
||||||
|
uni.navigateTo({ url: '/login-sub/index' })
|
||||||
|
reject(res)
|
||||||
|
} else if (res.statusCode < 300 && res.statusCode >= 200) {
|
||||||
// 2.1 提取核心数据 res.data
|
// 2.1 提取核心数据 res.data
|
||||||
resolve(res.data as IResData<T>)
|
resolve(res.data as IResData<T>)
|
||||||
} else if (res.statusCode === 401) {
|
} else if (res.statusCode === 401) {
|
||||||
// 401错误 -> 清理用户信息,跳转到登录页
|
// 401错误 -> 清理用户信息,跳转到登录页
|
||||||
// userStore.clearUserInfo()
|
uni.navigateTo({ url: '/login-sub/index' })
|
||||||
// uni.navigateTo({ url: '/pages/login/login' })
|
|
||||||
reject(res)
|
reject(res)
|
||||||
} else {
|
} else {
|
||||||
// 其他错误 -> 根据后端错误信息轻提示
|
// 其他错误 -> 根据后端错误信息轻提示
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue