import {ref} from 'vue'; import _ from 'lodash'; import {createEventHook, injectLocal, provideLocal} from "@vueuse/core"; import {toast} from "@/uni_modules/uv-ui-tools/libs/function"; const key = Symbol('VOLUNTARY_CART') export const useProvideVoluntaryCart = function (initId, n = '') { const id = ref(initId) const name = ref(n) const locking = ref(false) const total = ref(0) const list = ref([]) const selectedList = ref([]) const defaultSort = ref([]) const majorCounter = ref(0) // 本地排序使用 const resetCart = () => { total.value = 0 list.value = [] selectedList.value = [] majorCounter.value = 0 } const syncMajorGroupToSelected = (rows) => { if (selectedList.value.length) { rows.forEach(group => { const matcher = s => s.uniqueCode == group.uniqueCode const matchIdx = selectedList.value.findIndex(matcher) if (matchIdx > -1) { const match = selectedList.value[matchIdx] group.majors = match.majors group.isExpand = match.isExpand // replace in selectedList selectedList.value.splice(matchIdx, 1, group) } }) } } const syncMajorsToSelectedGroup = (majors, majorGroup) => { if (majorGroup.majors.length) { majors.forEach(m => { const match = majorGroup.majors.find(cache => m.id == cache.id && cache.selected) m.selected = !!match m.localPriority = match?.localPriority || 0 // 用于本地排序,待提交时,按此字段排序 }) } else { majors.forEach(m => { m.selected = false m.localPriority = 0 }) } } const recalculatePureSelectedList = async () => { // 过滤掉selectedList中,其majors元素全部selected=false的项 // 使用splice操作,防止更改selectedList引用 const abandonGroups = selectedList.value.filter(g => g.majors.every(m => !m.selected)) _.pull(selectedList.value, ...abandonGroups) return !!abandonGroups.length } const toggleMajorSelected = async (major, majorGroup, options) => { // validation if (!major.selected) { // major is unselected if (majorGroup.majors.filter(major => major.selected).length >= options.firedLimit.profession) { toast(`每个专业组最多选择${options.firedLimit.profession}个专业`) return Promise.reject('profession over limitation.') } if (!selectedList.value.includes(majorGroup)) { // major & majorGroup are both unselected if (selectedList.value.length >= options.firedLimit.groups) { toast(`最多选择${options.firedLimit.groups}个专业组`) return Promise.reject('group over limitation') } } } // toggle major selected state major.selected = !major.selected if (major.selected) { // set majorCounter with max value of major.localPriority in majorGroup // this logic is for edit mode majorCounter.value = Math.max(majorCounter.value, ...majorGroup.majors.filter(m => m.selected).map(m => m.localPriority)) // make current major localPriority to max value major.localPriority = ++majorCounter.value // if major is a new select element, add its parent to selectedList if (!selectedList.value.includes(majorGroup)) { selectedList.value.push(majorGroup) } return } // if major is unselect, recalculate selectedList await recalculatePureSelectedList() } const options = { id, name, locking, total, list, selectedList, majorCounter, defaultSort, resetCart, syncMajorsToSelectedGroup, syncMajorGroupToSelected, recalculatePureSelectedList, toggleMajorSelected } provideLocal(key, options) return options } export const useInjectVoluntaryCart = function () { return injectLocal(key) }