useVoluntaryCartInjection.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. import {ref} from 'vue';
  2. import _ from 'lodash';
  3. import {createEventHook, injectLocal, provideLocal} from "@vueuse/core";
  4. import {toast} from "@/uni_modules/uv-ui-tools/libs/function";
  5. const key = Symbol('VOLUNTARY_CART')
  6. export const useProvideVoluntaryCart = function (initId, n = '') {
  7. const id = ref(initId)
  8. const name = ref(n)
  9. const locking = ref(false)
  10. const total = ref(0)
  11. const list = ref([])
  12. const selectedList = ref([])
  13. const defaultSort = ref([])
  14. const majorCounter = ref(0) // 本地排序使用
  15. const resetCart = () => {
  16. total.value = 0
  17. list.value = []
  18. selectedList.value = []
  19. majorCounter.value = 0
  20. }
  21. const syncMajorGroupToSelected = (rows) => {
  22. if (selectedList.value.length) {
  23. rows.forEach(group => {
  24. const matcher = s => s.uniqueCode == group.uniqueCode
  25. const matchIdx = selectedList.value.findIndex(matcher)
  26. if (matchIdx > -1) {
  27. const match = selectedList.value[matchIdx]
  28. group.majors = match.majors
  29. group.isExpand = match.isExpand
  30. // replace in selectedList
  31. selectedList.value.splice(matchIdx, 1, group)
  32. }
  33. })
  34. }
  35. }
  36. const syncMajorsToSelectedGroup = (majors, majorGroup) => {
  37. if (majorGroup.majors.length) {
  38. majors.forEach(m => {
  39. const match = majorGroup.majors.find(cache => m.id == cache.id && cache.selected)
  40. m.selected = !!match
  41. m.localPriority = match?.localPriority || 0 // 用于本地排序,待提交时,按此字段排序
  42. })
  43. } else {
  44. majors.forEach(m => {
  45. m.selected = false
  46. m.localPriority = 0
  47. })
  48. }
  49. }
  50. const recalculatePureSelectedList = async () => {
  51. // 过滤掉selectedList中,其majors元素全部selected=false的项
  52. // 使用splice操作,防止更改selectedList引用
  53. const abandonGroups = selectedList.value.filter(g => g.majors.every(m => !m.selected))
  54. _.pull(selectedList.value, ...abandonGroups)
  55. return !!abandonGroups.length
  56. }
  57. const toggleMajorSelected = async (major, majorGroup, options) => {
  58. // validation
  59. if (!major.selected) {
  60. // major is unselected
  61. if (majorGroup.majors.filter(major => major.selected).length >= options.firedLimit.profession) {
  62. toast(`每个专业组最多选择${options.firedLimit.profession}个专业`)
  63. return Promise.reject('profession over limitation.')
  64. }
  65. if (!selectedList.value.includes(majorGroup)) {
  66. // major & majorGroup are both unselected
  67. if (selectedList.value.length >= options.firedLimit.groups) {
  68. toast(`最多选择${options.firedLimit.groups}个专业组`)
  69. return Promise.reject('group over limitation')
  70. }
  71. }
  72. }
  73. // toggle major selected state
  74. major.selected = !major.selected
  75. if (major.selected) {
  76. // set majorCounter with max value of major.localPriority in majorGroup // this logic is for edit mode
  77. majorCounter.value = Math.max(majorCounter.value, ...majorGroup.majors.filter(m => m.selected).map(m => m.localPriority))
  78. // make current major localPriority to max value
  79. major.localPriority = ++majorCounter.value
  80. // if major is a new select element, add its parent to selectedList
  81. if (!selectedList.value.includes(majorGroup)) {
  82. selectedList.value.push(majorGroup)
  83. }
  84. return
  85. }
  86. // if major is unselect, recalculate selectedList
  87. await recalculatePureSelectedList()
  88. }
  89. const options = {
  90. id, name, locking,
  91. total, list, selectedList, majorCounter,
  92. defaultSort, resetCart,
  93. syncMajorsToSelectedGroup,
  94. syncMajorGroupToSelected,
  95. recalculatePureSelectedList,
  96. toggleMajorSelected
  97. }
  98. provideLocal(key, options)
  99. return options
  100. }
  101. export const useInjectVoluntaryCart = function () {
  102. return injectLocal(key)
  103. }