123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 |
- import {ref, toValue, watch, nextTick, isRef} from 'vue';
- import {empty, func} from "@/uni_modules/uv-ui-tools/libs/function/test";
- import _ from "lodash";
- import {fnPlaceholder} from "@/utils/uni-helper";
- // 一般情况下用queryParams即可,但有可能有些全局参数不在queryParams里面,则用sharedData注入进来
- // 通过dependentKeys和independentKeys,获取请求必须的参数
- // dependentKeys是必须参数,independentKeys是非必须参数
- export const useConditionFactory = function (config, eventManager, queryParams, sharedData, console) {
- const {
- key, handler, autoInit, required, rule, allLabel, title, multiple,
- dependentKeys, independentKeys, keyName, keyValue
- } = config
- if (empty(key)) throw new Error('condition must define a key')
- if (!func(handler)) throw new Error('handler must be a function')
- const list = ref([])
- if (required && !rule.some(r => r.required)) {
- // 没有必填规则就自动创建一条
- const requiredRule = {required: true, message: `${title}不能为空`, transform: (v) => v + ''}
- config.rule = [...rule, requiredRule] // 不要直接修改rule,rule可能来自于conditionSharedConfig
- }
- const makePayload = async () => {
- const payload = {}
- const params = toValue(queryParams)
- // 先检查依赖项
- for (const key of dependentKeys) {
- const val = params[key]
- if (empty(val)) {
- // 只是给一个警告,reject的方式太重了,会让后续开发认为产生了不可修复问题。
- // 一般情况下缺必传字段,只需要等必传字段autoInit完成就会自动修复这个问题。
- // 当然万一运行不符合预期,这里也确实是需要着重检查的点。
- console.warn(`${config.key}: independent key ${key} is required, wait for next turn.`)
- return new Promise(fnPlaceholder).then()
- // return Promise.reject('some message')
- }
- payload[key] = val
- }
- for (const key of independentKeys) {
- payload[key] = params[key]
- }
- return {...toValue(sharedData), ...payload}
- }
- const loadData = async () => {
- eventManager.push('loadData calling', key)
- const payload = await makePayload()
- const results = await config.handler(payload)
- console.log('dataManager data loaded', key, results)
- const processData = function (results) {
- if (allLabel && !required) {
- const add = keyValue ? {[keyName]: allLabel, [keyValue]: ''} : allLabel
- list.value = [add, ...results] // 不直接修改,可能会影响缓存结果
- } else {
- list.value = results
- }
- const current = toValue(queryParams)[key]
- const currentInvalid = (val) => {
- const valSource = list.value.map(i => keyValue ? i[keyValue] : i)
- const diff = _.difference(valSource, [].concat(val))
- console.log('loadData invalid current:', val, ', diff', diff)
- return diff.length > 0
- }
- if (!empty(current) && currentInvalid(current)) {
- console.log('loadData clear invalid', key, current)
- queryParams.value[key] = multiple ? [] : ''
- }
- if (required && autoInit && empty(current)) {
- const first = _.first(list.value)
- const firstValue = keyValue ? first[keyValue] : first
- if (first) queryParams.value[key] = multiple ? [firstValue] : firstValue
- console.log('loadData auto init', key, firstValue)
- }
- eventManager.pop('loadData called', key)
- }
- if (isRef(results)) {
- const pureResults = toValue(results)
- if (empty(pureResults)) {
- // 此时没有数据,说明后续可能会更新,使用watch监听即可
- watch(results, (values) => processData(values))
- } else {
- processData(pureResults)
- }
- } else {
- processData(results)
- }
- }
- // 数据加载
- if (!dependentKeys.length) {
- // 无依赖项,直接调用。这里使用了nextTick做保险,万一立即进行校验,要保证uv-form渲染之后才能进行
- nextTick(async () => await loadData())
- } else {
- // 有依赖项,建立监听,依赖变更时重新加载数据
- const watches = dependentKeys.map(k => () => toValue(queryParams)[k])
- watch(watches, async () => await loadData(), {immediate: true})
- }
- return {list, config}
- }
|