import {computed, ref, watch} from 'vue'; import {toValue} from "@vueuse/core"; import {useInjectVoluntaryCart} from "@/pages/voluntary/hooks/useVoluntaryCartInjection"; import {useInjectVoluntaryData} from "@/hooks/useVoluntaryDataInjection"; import MxConst from "@/common/mxConst"; export const useVoluntarySortService = function (popupRef, defaultSort = []) { const {selectedList} = useInjectVoluntaryCart() const {voluntaryData} = useInjectVoluntaryData() const showPopup = computed(() => toValue(popupRef).showPopup) const cancelSortText = computed(() => toValue(defaultSort).length ? '重置排序' : '清除排序') // sort related const firedSorts = ref([]) const localSort = ref([]) // 这里放本地手工操作影响的排序结果 const sortList = ref([{ name: '录取概率从低到高', short: '录取率', icon: 'arrow-downward', compare: (a, b) => { const aRatio = a.enrollRatio * 1 const bRatio = b.enrollRatio * 1 return aRatio - bRatio } }, { name: '录取概率从高到低', short: '录取率', icon: 'arrow-upward', compare: (a, b) => { const aRatio = a.enrollRatio * 1 const bRatio = b.enrollRatio * 1 return bRatio - aRatio } }, { name: '最低位次从低到高', short: '位次', icon: 'arrow-downward', compare: (a, b) => { const aSeat = a.history?.seat || 9999 const bSeat = b.history?.seat || 9999 return bSeat - aSeat // 数字越小位次越高 } }, { name: '最低位次从高到低', short: '位次', icon: 'arrow-upward', compare: (a, b) => { const aSeat = a.history?.seat || -1 const bSeat = b.history?.seat || -1 return aSeat - bSeat } }, { name: '院校排名从低到高', short: '院校排名', icon: 'arrow-downward', compare: (a, b) => { const aRank = a.university.ranking * 1 const bRank = b.university.ranking * 1 return bRank - aRank // 数字越小排名越高 } }, { name: '院校排名从高到低', short: '院校排名', icon: 'arrow-upward', compare: (a, b) => { const aRank = a.university.ranking * 1 const bRank = b.university.ranking * 1 return aRank - bRank } }]) const resetCompare = (a, b) => { const restoreSort = toValue(localSort).length ? toValue(localSort) : toValue(defaultSort) let aIdx = restoreSort.findIndex(id => id == a.uniqueCode) let bIdx = restoreSort.findIndex(id => id == b.uniqueCode) if (aIdx === -1) aIdx = 9999 if (bIdx === -1) bIdx = 9999 return aIdx - bIdx } const sequenceOptions = computed(() => { // Note: Here we return a 2 dimension array, because `u-picker` is a multi-column picker return selectedList.value.map((item, index) => ({ value: index, text: generateSeq(index) })) }) // methods const generateSeq = (index) => { switch (toValue(voluntaryData).sort) { case 'letter': return String.fromCharCode(65 + index) default: return index + 1 } } const sortInterrupt = (sorts = null) => { firedSorts.value = [] localSort.value = sorts || toValue(selectedList).map(g => g.uniqueCode) } const _orderByAndThen = () => { const sortsRef = toValue(firedSorts) toValue(selectedList).sort((a, b) => { for (let idx = 0; idx < sortsRef.length; idx++) { const curSort = sortsRef[idx] const curCompare = curSort.compare(a, b) if (curCompare === 0) continue // 如果先选条件相等才比较下一条 return curCompare } return 0 }) } const handleSort = (sort) => { // 搜索已经存在的互斥条件 const sortsRef = toValue(firedSorts) const idx = sortsRef.findIndex(s => s.short == sort.short) if (idx != -1) sortsRef.splice(idx, 1) sortsRef.push(sort) _orderByAndThen() } const handleSortRemove = (sort) => { const sortsRef = toValue(firedSorts) const idx = sortsRef.indexOf(sort) sortsRef.splice(idx, 1) toValue(selectedList).sort(resetCompare) _orderByAndThen() } const handleSortReset = () => { toValue(selectedList).sort(resetCompare) firedSorts.value = [] } const handleMoveUp = (group) => { const idx = selectedList.value.indexOf(group) const target = idx - 1 if (target > -1) { selectedList.value.splice(idx, 1) selectedList.value.splice(target, 0, group) sortInterrupt() } } const handleMoveDown = (group) => { const idx = selectedList.value.indexOf(group) const target = idx + 1 if (target < selectedList.value.length) { selectedList.value.splice(idx, 1) selectedList.value.splice(target, 0, group) sortInterrupt() } } const getSelectedSortedMajors = (group) => { return group.majors.filter(m => m.selected).sort(MxConst.recommendMajorSortFn) } // hooks watch(() => toValue(selectedList).map(g => g.uniqueCode), (sorts) => { if (!showPopup.value) { sortInterrupt(sorts) } }) return { firedSorts, localSort, sortList, cancelSortText, sequenceOptions, generateSeq, sortInterrupt, handleSort, handleSortReset, handleSortRemove, getSelectedSortedMajors, handleMoveDown, handleMoveUp } }