123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- import {ref, watch, computed, nextTick} from 'vue'
- import {createEventHook, injectLocal, provideLocal} from "@vueuse/core";
- import {useProvidePaperService} from "@/components/mx-paper/usePaperInjection";
- import {numberToChinese} from "@/utils";
- import {useProvideQuestionOptionFormatter} from "@/components/mx-question-content/useQuestionOptionInjection";
- import {useProvideMathJaxSwitch} from "@/components/mx-question-content/useMathJaxSwitchInjection";
- import {toast} from "@/uni_modules/uv-ui-tools/libs/function";
- import {empty, func} from "@/uni_modules/uv-ui-tools/libs/function/test";
- import mxConst from "@/common/mxConst";
- import {fnPlaceholder} from "@/utils/uni-helper";
- const key = Symbol('STEP_PAPER_SERVICE')
- export const useProvideStepPaper = (name, answerFormatter = (v) => v) => {
- const title = ref(name)
- const welcomeShow = ref(true)
- const resultShow = ref(false)
- const step = ref(0)
- const steps = ref([])
- const stepQuestionContainer = ref(new Map())
- const answerData = ref(new Map())
- const beginEvent = createEventHook()
- const stepStartEvent = createEventHook()
- const finishEvent = createEventHook()
- const currentStep = computed(() => steps.value[step.value] || {})
- const currentStepQuestions = computed(() => stepQuestionContainer.value.get(currentStep.value.id))
- const paperData = computed(() => ({
- name: name,
- allowAnswer: true,
- allowScore: false,
- questions: currentStepQuestions.value
- }))
- const overridePaperService = {
- commitQuestion: async (commits) => {
- // step paper只涉及本地提交
- // 没有更改doChunk,业务上还是可以依靠它来驱动
- commits.forEach(item => {
- answerData.value.set(item.questionId, item.answer)
- })
- },
- commitPaper: async () => {
- // step paper表示往前走一步
- // 此进是强制走步,此时将触发finish
- step.value += 1
- }
- }
- // 只重写了step需要影响的部分
- const paperService = useProvidePaperService(paperData, overridePaperService)
- const optionFormatter = (options) => options.map(o => ({code: o.id, option: o.label}))
- const optionClass = (q) => mxConst.question.isRadio(q.typeId) ? 'pt-10' : ''
- useProvideQuestionOptionFormatter(optionFormatter, optionClass)
- useProvideMathJaxSwitch(true) // 明确此类测评没有包含任何公式转换
- const hasNextStep = computed(() => step.value < steps.value.length - 1)
- const hasPrevStep = computed(() => step.value > 0)
- const tryGoNextStep = () => {
- if (!hasNextStep.value) return toast('已经是最后一部分了')
- step.value += 1
- paperService.index.value = 0
- }
- const tryGoPrevStep = () => {
- if (!hasPrevStep.value) return toast('已经是第一题了')
- step.value -= 1
- nextTick().then(() => {
- // 需要等待题加载完毕,再重置题的位置
- paperService.index.value = paperService.questions.value.length - 1
- })
- }
- watch([welcomeShow, resultShow], async () => {
- if (!welcomeShow.value && !resultShow.value) {
- await beginEvent.trigger()
- }
- })
- watch(currentStep, async (step) => {
- if (!empty(step)) {
- await stepStartEvent.trigger(step.id)
- }
- })
- watch(() => step.value >= steps.value.length, async (complete) => {
- if (complete) {
- // 转成API要求的标准格式
- const details = []
- for (const [key, value] of answerData.value) {
- details.push({
- questionId: key,
- answer: answerFormatter(value)
- })
- }
- await finishEvent.trigger({details})
- resultShow.value = true
- }
- })
- const options = {
- ...paperService,
- title,
- welcomeShow,
- resultShow,
- step,
- steps,
- currentStep,
- stepQuestionContainer,
- hasPrevStep,
- hasNextStep,
- tryGoPrevStep,
- tryGoNextStep,
- paperData,
- answerData,
- onBegin: beginEvent.on,
- onStepStart: stepStartEvent.on,
- onFinish: finishEvent.on
- }
- provideLocal(key, options)
- return options
- }
- export const useInjectStepPaper = () => {
- return injectLocal(key)
- }
- export const stepFormatter = (steps) => {
- steps.forEach((s, i) => s.name = numberToChinese(i + 1))
- return steps
- }
- export const questionsFormatter = (questions, typeId, options = null) => {
- questions.forEach((q, i) => {
- const op = func(options) ? options(q) : options
- q.questionId = q.questionId || q.id
- q.typeId = typeId
- q.seq = i + 1
- q.options = op || q.options
- })
- return questions
- }
|