import { reactive, computed, watch, ref, unref, isRef, nextTick } from 'vue' import useFetch from '@/hooks/useFetch' import { ExtractApiResponse } from 'api-type' import type { Ref } from 'vue' export interface DataModel { subject?: string question?: number group?: number } interface Group { label: string value: number } type QuestionList = ExtractApiResponse<'getMainQuestionList'>[0] & { label: string value: number } const useOptions = (types: (keyof DataModel)[], initModel?: DataModel | Ref, autoFill = true) => { const dataModel = reactive(unref(initModel) || {}) if (isRef(initModel)) { watch( initModel, () => { Object.assign(dataModel, unref(initModel)) }, { deep: true } ) } const changeModelValue = (key: T) => { return (v: DataModel[T]) => { dataModel[key] = v } } const { fetch: getSubjectList, result: subjectResult } = useFetch('getSubjectList') const { fetch: getMainQuestionList, result: mainQuestionListResult, reset: resetQuestionFetch, } = useFetch('getMainQuestionList') const { fetch: getMainQuestionInfo, result: mainQuestionInfo, reset: resetMainQuestionFetch, } = useFetch('getMainQuestionInfo') const subjectList = computed(() => { return ( subjectResult.value?.result?.map((subject) => { return { ...subject, value: subject.code, label: subject.name } }) || [] ) }) const mainQuestionList = computed(() => { return ( mainQuestionListResult.value?.map((v) => { return { ...v, label: v.title, value: v.mainNumber, } }) || [] ) }) const groupList = computed(() => { return mainQuestionInfo.value?.groupNumber ? Array.from({ length: mainQuestionInfo.value.groupNumber }).map((_, i) => { return { value: i + 1, label: `第${i + 1}组`, } }) : [] }) const groupListWithAll = computed(() => { return groupList.value?.length ? [{ label: '全部', value: void 0 } as unknown as Group].concat(groupList.value) : [] }) watch( () => dataModel.subject, () => { if (types.includes('question') && dataModel.subject) { resetQuestionFetch() resetMainQuestionFetch() changeModelValue('question')(void 0) changeModelValue('group')(void 0) getMainQuestionList({ subjectCode: dataModel.subject }) } }, { immediate: true } ) watch( () => dataModel.question, () => { if (types.includes('group') && dataModel.subject && dataModel.question) { resetMainQuestionFetch() changeModelValue('group')(void 0) getMainQuestionInfo({ subjectCode: dataModel.subject, mainNumber: dataModel.question }) } }, { immediate: true } ) if (autoFill) { watch( subjectList, () => { if (subjectList.value?.[0]?.value && !dataModel.subject) { changeModelValue('subject')(subjectList.value[0].value) } }, { deep: true } ) watch( mainQuestionList, () => { if (mainQuestionList.value?.[0]?.value) { changeModelValue('question')(mainQuestionList.value[0].value) } }, { deep: true } ) watch( groupList, () => { if (groupList.value?.[0]?.value) { changeModelValue('group')(groupList.value[0].value) } }, { deep: true } ) } const initFinish = ref(false) const destroyInit = watch(dataModel, () => { if (types.every((t) => dataModel[t])) { nextTick(() => { initCallbacks.forEach((cb) => cb(dataModel)) initFinish.value = true destroyInit() }) } }) const initCallbacks: ((d: DataModel) => void)[] = [] const onOptionInit = (cb: (d?: DataModel) => void) => { initCallbacks.push(cb) } const forceRefresh = () => { getSubjectList({ pageNumber: 1, pageSize: 9999 }) } if (types.includes('subject')) { forceRefresh() } return { subjectList, mainQuestionList, groupList, groupListWithAll, dataModel, initFinish, onOptionInit, changeModelValue, forceRefresh, } } export default useOptions