123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- 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)
- }
|