123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373 |
- <template>
- <uv-popup ref="popup" mode="bottom" round="16" closeable>
- <view class="h-[50px] px-40 fx-row fx-bet-cen text-main text-lg font-bold">
- <template v-if="!id">
- 志愿表预览
- </template>
- <view v-else class="fx-row flex-1 pr-30">
- <text v-if="!nameEditing">{{ name }}</text>
- <uv-input v-else v-model="name" placeholder="志愿表名称"/>
- <uv-icon name="edit-pen" size="18" class="ml-10" @click="nameEditing=!nameEditing"/>
- </view>
- <uv-tags icon="list-dot" text="快速排序" plain class="mr-50" @click="openSortList"/>
- </view>
- <scroll-view :scroll-y="!anyDragging" class="bg-bg" style="height: 50vh" lower-threshold="100"
- @scrolltolower="handleGroupScroll">
- <uv-sticky v-if="firedSorts.length" :offsetTop="-44">
- <view class="px-20 pb-20 fx-row bg-white">
- <uv-tags v-for="s in firedSorts" :key="s.name" :text="s.short" :icon="s.icon" size="mini"
- type="success" closable plain-fill @close="handleSortRemove(s)"/>
- </view>
- </uv-sticky>
- <view class="p-20 fx-col gap-20">
- <view v-for="(college,index) in pagedSelectedList" class="fx-row fx-bet-sta bg-white mx-card">
- <view class="ml-10 mb-10 text-sm">
- <text class="fx-row rounded-b-full px-15 pt-5 pb-10 text-white bg-primary">
- {{ generateSeq(index) }}
- </text>
- </view>
- <view class="flex-1 p-20 fx-col">
- <view class="font-bold">
- {{ college.university.name }}
- <!-- TODO:志愿表还未保存group信息,所以这里显示会在编辑时表现不一致 -->
- <template v-if="false">({{ college.recruitPlan.group }})</template>
- ({{ college.recruitPlan.collegeCode }})
- </view>
- <view class="fx-row fx-bet-cen mt-10 text-content text-2xs gap-20">
- <view>录取概率:
- <view class="font-bold text-main">
- {{ college.enrollRatio || '-' }}%
- </view>
- </view>
- <view>最低位次:
- <view class="font-bold text-main">
- {{ college.history && college.history.seat || '-' }}
- </view>
- </view>
- <view>院校排名:
- <view class="font-bold text-main">
- {{ college.university.ranking || '-' }}
- </view>
- </view>
- </view>
- <view class="fx-row gap-20 my-20">
- <uv-button :disabled="selectedList.length<2" type="primary" size="mini" plain
- shape="circle" icon="arrow-down-fill" :text="generateSeq(index)"
- icon-color="primary" @click="openSeqSelect(index)"/>
- <uv-button :disabled="index==0" type="primary" size="mini" plain shape="circle"
- icon="arrow-up" icon-color="primary" @click="handleMoveUp(college)"/>
- <uv-button :disabled="index==selectedList.length-1" type="primary" size="mini" plain
- shape="circle" icon="arrow-down" icon-color="primary"
- @click="handleMoveDown(college)"/>
- <uv-button type="primary" size="mini" plain shape="circle" icon="trash"
- icon-color="primary" @click="handleRemoveAll(college)"/>
- </view>
- <m-drag ref="drag" :list="getSelectedSortedMajors(college)" :item-height="44"
- @change="handleDragComplete">
- <template #default="{item:major,index:majorIndex}">
- <view class="fx-row items-center text-xs text-content h-[44px] box-border mx-border-b">
- <view class="flex-1 truncate">
- <text v-if="majorIndex>-1" class="mr-20">{{ majorIndex + 1 }}</text>
- <text :class="{'highlight-major': isFormedMajorFired(major)}">
- {{ major.marjorName }}[{{ major.marjorBelongs }}]
- </text>
- </view>
- <!-- 因为手机上区域比较小,只保留了拖拽排序 -->
- <uv-icon v-if="false" name="arrow-up" size="20px" class="mr10"
- @click="handleMajorUp(major, college)"></uv-icon>
- <uv-icon v-if="false" name="arrow-down" size="20px" class="mr10"
- @click="handleMajorDown(major, college)"></uv-icon>
- <uv-icon name="trash" size="20px" class="mr10"
- @click="handleMajorDelete(major, college)"></uv-icon>
- </view>
- </template>
- </m-drag>
- </view>
- </view>
- </view>
- </scroll-view>
- <view class="h-[50px] px-40 fx-row items-center mx-border-t">
- <uv-button type="primary" text="保存志愿表" shape="circle" :loading="locking"
- @click="handleSave"></uv-button>
- </view>
- <uv-action-sheet ref="actionSheet" :actions="sortList" :cancel-text="cancelSortText" @select="handleSort"
- @cancel="handleSortReset"/>
- <!-- We don't use `u-action-sheet` because there maybe a great number of seq options -->
- <uv-picker ref="picker" title="指定志愿顺序" :columns="[sequenceOptions]" :default-index="[seqIndex]"
- @confirm="handleSeq"/>
- </uv-popup>
- </template>
- <script setup>
- import {ref, computed, watch} from 'vue';
- import {useInjectVoluntaryCart} from "@/pages/voluntary/hooks/useVoluntaryCartInjection";
- import {toValue} from "@vueuse/core";
- import {useVoluntarySortService} from "@/pages/voluntary/hooks/useVoluntarySortService";
- import {useInjectVoluntaryMajorHighlight} from "@/pages/voluntary/hooks/useVoluntaryMajorHighlightInjection";
- import {confirmAsync} from "@/utils/uni-helper";
- import {useInjectVoluntaryAssistant} from "@/pages/voluntary/hooks/useVoluntaryAssistantInjection";
- import {useInjectVoluntaryHeader} from "@/pages/voluntary/hooks/useVoluntaryHeaderInjection";
- const popup = ref(null)
- const drag = ref(null)
- const picker = ref(null)
- const actionSheet = ref(null)
- const seqIndex = ref(0)
- const nameEditing = ref(false) // 暂时不允许修改名称
- const {id, name, locking, selectedList, defaultSort, recalculatePureSelectedList} = useInjectVoluntaryCart()
- const {isFormedMajorFired, snapshotSearchingMajorWhenApply} = useInjectVoluntaryMajorHighlight()
- const {
- firedSorts, sortList, cancelSortText, generateSeq, sequenceOptions,
- handleSort, handleSortReset, handleSortRemove,
- getSelectedSortedMajors, sortInterrupt,
- handleMoveDown, handleMoveUp
- } = useVoluntarySortService(popup, defaultSort)
- const {isMock} = useInjectVoluntaryHeader()
- const {save} = useInjectVoluntaryAssistant()
- const anyDragging = computed(() => drag.value?.some(d => d.dragging))
- // optimization for faster rendering
- const localPageNum = ref(1)
- const localPageSize = ref(4)
- const pagedSelectedList = computed(() => {
- return selectedList.value.slice(0, toValue(localPageNum) * toValue(localPageSize))
- })
- const handleGroupScroll = () => {
- if (toValue(pagedSelectedList).length >= toValue(selectedList).length) return
- localPageNum.value += 1
- }
- const openSortList = () => {
- actionSheet.value.open()
- }
- const handleDragComplete = (newList, oldList) => {
- // make localPriority exchange when drag complete.
- const copyPriorities = oldList.map(i => i.localPriority)
- copyPriorities.forEach((p, i) => newList[i].localPriority = p)
- }
- const handleRemoveAll = async (college) => {
- await confirmAsync('确认删除该专业组下的全部专业?')
- college.majors.forEach(m => {
- m.selected = false
- snapshotSearchingMajorWhenApply(m)
- })
- recalculatePureSelectedList()
- sortInterrupt()
- }
- // sort for major item
- const handleMajorUp = (major, majorGroup) => {
- // TODO: HM-DragSorts 已经没有再使用了,所以不存在深拷贝的问题,但这个方法目前没有使用,先不优化
- const source = getSelectedSortedMajors(majorGroup)
- // HM-DragSorts clone element will cause index error
- const index = source.findIndex(s => s.marjorBelongs == major.marjorBelongs)
- const targetIndex = index - 1
- // exchange two majors' localPriority
- if (targetIndex >= 0) {
- major = source[index] // this is the original major
- const targetMajor = source[targetIndex]
- const temp = major.localPriority
- major.localPriority = targetMajor.localPriority
- targetMajor.localPriority = temp
- }
- }
- const handleMajorDown = (major, majorGroup) => {
- // TODO: HM-DragSorts 已经没有再使用了,所以不存在深拷贝的问题,但这个方法目前没有使用,先不优化
- const source = getSelectedSortedMajors(majorGroup)
- // HM-DragSorts clone element will cause index error
- const index = source.findIndex(s => s.marjorBelongs == major.marjorBelongs)
- const targetIndex = index + 1
- // exchange two majors' localPriority
- if (targetIndex < source.length) {
- major = source[index] // this is the original major
- const targetMajor = source[targetIndex]
- const temp = major.localPriority
- major.localPriority = targetMajor.localPriority
- targetMajor.localPriority = temp
- }
- }
- const handleMajorDelete = (major) => {
- major.selected = false
- snapshotSearchingMajorWhenApply(major)
- if (recalculatePureSelectedList()) sortInterrupt()
- }
- const openSeqSelect = (groupIndex) => {
- seqIndex.value = groupIndex
- picker.value.open()
- }
- const handleSeq = ({indexs}) => {
- const oldIndex = seqIndex.value
- const newIndex = indexs[0]
- if (oldIndex != newIndex) {
- const seqGroup = selectedList.value[oldIndex]
- selectedList.value.splice(oldIndex, 1)
- selectedList.value.splice(newIndex, 0, seqGroup)
- sortInterrupt()
- }
- }
- const handleSave = async () => {
- await save(isMock.value)
- }
- const open = () => {
- localPageNum.value = 1
- popup.value.open()
- }
- const close = () => {
- popup.value.close()
- }
- defineExpose({open, close})
- // export default {
- // props: {
- // id: {
- // type: String | Number,
- // default: 0
- // },
- // name: {
- // type: String,
- // default: ''
- // },
- // show: {
- // type: Boolean,
- // default: false
- // },
- // selectedList: {
- // type: Array,
- // default: () => []
- // },
- // defaultSort: {
- // type: Array,
- // default: () => []
- // },
- // locking: {
- // type: Boolean,
- // default: false
- // }
- // },
- // data() {
- // return {
- // nameEditing: false,
- // confirmGroup: null,
- // showConfirm: false,
- // showSort: false,
- // showSeq: false,
- // seqIndex: 0,
- // }
- // },
- // watch: {
- // show: function (val) {
- // // u-popup will release dom elements when not showing
- // // so reset the current page number here
- // if (val) this.localPageNum = 1
- // }
- // },
- // methods: {
- // getSelectedSortedMajors(group) {
- // return group.majors.filter(m => m.selected).sort(MxConst.recommendMajorSortFn)
- // },
- // getGroupHeight(group) {
- // const majors = this.getSelectedSortedMajors(group)
- // return majors.length * 45
- // },
- // openSeqSelect(groupIndex) {
- // this.seqIndex = groupIndex
- // this.showSeq = true
- // },
- // handleSeq({indexs}) {
- // const oldIndex = this.seqIndex
- // const newIndex = indexs[0]
- // if (oldIndex != newIndex) {
- // const seqGroup = this.selectedList[oldIndex]
- // this.selectedList.splice(oldIndex, 1)
- // this.selectedList.splice(newIndex, 0, seqGroup)
- // this.sortInterrupt()
- // }
- // this.showSeq = false
- // },
- // close() {
- // this.$emit('closeVolunteer')
- // },
- // open() {
- //
- // },
- // save() {
- // this.$emit('save')
- // },
- // handleRemoveAll() {
- // this.confirmGroup.majors.forEach(m => {
- // m.selected = false
- // this.snapshotSearchingMajorWhenApply(m)
- // })
- // this.$emit('change')
- // this.showConfirm = false
- // },
- // // sort for major item
- // handleMajorUp(major, majorGroup) {
- // const source = this.getSelectedSortedMajors(majorGroup)
- // // HM-DragSorts clone element will cause index error
- // const index = source.findIndex(s => s.marjorBelongs == major.marjorBelongs)
- // const targetIndex = index - 1
- // // exchange two majors' localPriority
- // if (targetIndex >= 0) {
- // major = source[index] // this is the original major
- // const targetMajor = source[targetIndex]
- // const temp = major.localPriority
- // major.localPriority = targetMajor.localPriority
- // targetMajor.localPriority = temp
- // }
- // },
- // handleMajorDown(major, majorGroup) {
- // const source = this.getSelectedSortedMajors(majorGroup)
- // // HM-DragSorts clone element will cause index error
- // const index = source.findIndex(s => s.marjorBelongs == major.marjorBelongs)
- // const targetIndex = index + 1
- // // exchange two majors' localPriority
- // if (targetIndex < source.length) {
- // major = source[index] // this is the original major
- // const targetMajor = source[targetIndex]
- // const temp = major.localPriority
- // major.localPriority = targetMajor.localPriority
- // targetMajor.localPriority = temp
- // }
- // },
- // deleteMajor(major, majorGroup) {
- // const source = this.getSelectedSortedMajors(majorGroup)
- // // HM-DragSorts clone element will cause index error
- // const index = source.findIndex(s => s.marjorBelongs == major.marjorBelongs)
- // major = source[index] // this is the original major
- // major.selected = false
- // this.snapshotSearchingMajorWhenApply(major)
- // this.$emit('change')
- // },
- // handleMajorDrag(group, event) {
- // const source = this.getSelectedSortedMajors(group)
- // const oldIndex = event.index * 1
- // const newIndex = event.moveTo * 1
- // if (oldIndex == newIndex) return
- // // get localPriority one by one
- // const oldSeq = source.map(m => m.localPriority)
- // const oldMajor = source[oldIndex]
- // const newMajor = source[newIndex]
- // const newSource = [...source]
- // newSource.splice(oldIndex, 1)
- // newSource.splice(newIndex, 0, oldMajor)
- // // assign oldSeq to newSource one by one
- // newSource.forEach((m, idx) => {
- // m.localPriority = oldSeq[idx]
- // })
- // }
- // }
- // }
- </script>
- <style scoped lang="scss">
- .uv-button-wrapper {
- flex: 1 !important;
- }
- </style>
|