useVoluntarySortService.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. import {useInjectVoluntaryCart} from "@/pagesOther/pages/vhs/hooks/useVoluntaryCartInjection";
  2. import {useInjectVoluntaryData} from "@/pagesOther/hooks/useVoluntaryDataInjection";
  3. import {recommendMajorSortFn} from "@/utils/common";
  4. export const useVoluntarySortService = function (popupRef, defaultSort = []) {
  5. const {selectedList} = useInjectVoluntaryCart()
  6. const {voluntaryData} = useInjectVoluntaryData()
  7. const showPopup = computed(() => toValue(popupRef).showPopup)
  8. const cancelSortText = computed(() => toValue(defaultSort).length ? '重置排序' : '清除排序')
  9. // sort related
  10. const firedSorts = ref([])
  11. const localSort = ref([]) // 这里放本地手工操作影响的排序结果
  12. const sortList = ref([{
  13. name: '录取概率从低到高',
  14. short: '录取率',
  15. icon: 'arrow-downward',
  16. compare: (a, b) => {
  17. const aRatio = a.enrollRatio * 1
  18. const bRatio = b.enrollRatio * 1
  19. return aRatio - bRatio
  20. }
  21. }, {
  22. name: '录取概率从高到低',
  23. short: '录取率',
  24. icon: 'arrow-upward',
  25. compare: (a, b) => {
  26. const aRatio = a.enrollRatio * 1
  27. const bRatio = b.enrollRatio * 1
  28. return bRatio - aRatio
  29. }
  30. }, {
  31. name: '最低位次从低到高',
  32. short: '位次',
  33. icon: 'arrow-downward',
  34. compare: (a, b) => {
  35. const aSeat = a.history?.seat || 9999
  36. const bSeat = b.history?.seat || 9999
  37. return bSeat - aSeat // 数字越小位次越高
  38. }
  39. }, {
  40. name: '最低位次从高到低',
  41. short: '位次',
  42. icon: 'arrow-upward',
  43. compare: (a, b) => {
  44. const aSeat = a.history?.seat || -1
  45. const bSeat = b.history?.seat || -1
  46. return aSeat - bSeat
  47. }
  48. }, {
  49. name: '院校排名从低到高',
  50. short: '院校排名',
  51. icon: 'arrow-downward',
  52. compare: (a, b) => {
  53. const aRank = a.university.ranking * 1
  54. const bRank = b.university.ranking * 1
  55. return bRank - aRank // 数字越小排名越高
  56. }
  57. }, {
  58. name: '院校排名从高到低',
  59. short: '院校排名',
  60. icon: 'arrow-upward',
  61. compare: (a, b) => {
  62. const aRank = a.university.ranking * 1
  63. const bRank = b.university.ranking * 1
  64. return aRank - bRank
  65. }
  66. }])
  67. const resetCompare = (a, b) => {
  68. const restoreSort = toValue(localSort).length ? toValue(localSort) : toValue(defaultSort)
  69. let aIdx = restoreSort.findIndex(id => id == a.uniqueCode)
  70. let bIdx = restoreSort.findIndex(id => id == b.uniqueCode)
  71. if (aIdx === -1) aIdx = 9999
  72. if (bIdx === -1) bIdx = 9999
  73. return aIdx - bIdx
  74. }
  75. const sequenceOptions = computed(() => {
  76. // Note: Here we return a 2 dimension array, because `u-picker` is a multi-column picker
  77. return selectedList.value.map((item, index) => ({
  78. value: index,
  79. text: generateSeq(index)
  80. }))
  81. })
  82. // methods
  83. const generateSeq = (index) => {
  84. switch (toValue(voluntaryData).sort) {
  85. case 'letter':
  86. return String.fromCharCode(65 + index)
  87. default:
  88. return index + 1
  89. }
  90. }
  91. const sortInterrupt = (sorts = null) => {
  92. firedSorts.value = []
  93. localSort.value = sorts || toValue(selectedList).map(g => g.uniqueCode)
  94. }
  95. const _orderByAndThen = () => {
  96. const sortsRef = toValue(firedSorts)
  97. toValue(selectedList).sort((a, b) => {
  98. for (let idx = 0; idx < sortsRef.length; idx++) {
  99. const curSort = sortsRef[idx]
  100. const curCompare = curSort.compare(a, b)
  101. if (curCompare === 0) continue // 如果先选条件相等才比较下一条
  102. return curCompare
  103. }
  104. return 0
  105. })
  106. }
  107. const handleSort = (sort) => {
  108. // 搜索已经存在的互斥条件
  109. const sortsRef = toValue(firedSorts)
  110. const idx = sortsRef.findIndex(s => s.short == sort.short)
  111. if (idx != -1) sortsRef.splice(idx, 1)
  112. sortsRef.push(sort)
  113. _orderByAndThen()
  114. }
  115. const handleSortRemove = (sort) => {
  116. const sortsRef = toValue(firedSorts)
  117. const idx = sortsRef.indexOf(sort)
  118. sortsRef.splice(idx, 1)
  119. toValue(selectedList).sort(resetCompare)
  120. _orderByAndThen()
  121. }
  122. const handleSortReset = () => {
  123. toValue(selectedList).sort(resetCompare)
  124. firedSorts.value = []
  125. }
  126. const handleMoveUp = (group) => {
  127. const idx = selectedList.value.indexOf(group)
  128. const target = idx - 1
  129. if (target > -1) {
  130. selectedList.value.splice(idx, 1)
  131. selectedList.value.splice(target, 0, group)
  132. sortInterrupt()
  133. }
  134. }
  135. const handleMoveDown = (group) => {
  136. const idx = selectedList.value.indexOf(group)
  137. const target = idx + 1
  138. if (target < selectedList.value.length) {
  139. selectedList.value.splice(idx, 1)
  140. selectedList.value.splice(target, 0, group)
  141. sortInterrupt()
  142. }
  143. }
  144. const getSelectedSortedMajors = (group) => {
  145. return group.majors.filter(m => m.selected).sort(recommendMajorSortFn)
  146. }
  147. // hooks
  148. watch(() => toValue(selectedList).map(g => g.uniqueCode), (sorts) => {
  149. if (!showPopup.value) {
  150. sortInterrupt(sorts)
  151. }
  152. })
  153. return {
  154. firedSorts, localSort, sortList, cancelSortText,
  155. sequenceOptions, generateSeq, sortInterrupt,
  156. handleSort, handleSortReset, handleSortRemove,
  157. getSelectedSortedMajors,
  158. handleMoveDown, handleMoveUp
  159. }
  160. }