useVoluntarySortService.js 5.8 KB

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