UNPKG

@ams-team/ams

Version:

Admin Materials System.

235 lines (218 loc) 9.62 kB
import { deepExtend, get } from '../../../utils'; import * as fieldGetSet from '../field-get-set'; import { httpRequestTypeExcludeGet } from '../../request'; // fields export const RESET_GET_SET = { get: fieldGetSet.get, set: fieldGetSet.set, view: fieldGetSet.view }; // debounce timer let timer; const optionsCache = {}; const lockQuerys = {}; // 场景一:远程select、关键字搜索、最小化回填、options缓存 // isInitEmpty: false, // isCache: true, // isLock: true, // isMiniBackfill: true, // 场景二:远程checkbox或者radio、通过接口请求options、无关键字搜索、完整列表回填 // isInitEmpty: true, // isCache: true, // isLock: true, // isMiniBackfill: false, export const SELECT_REMOTE = { remoteConfig: { labelKey: 'name', valueKey: 'id', queryKey: 'query', action: '', dataPath: 'data.list', debounce: 500, // 初始化时是否自动发起请求 isInitRemoteOptions: true, // 无参数时发起请求 isInitEmpty: false, // 通过action缓存合并options数据,缓存数据只会用于回填,array类型的options不支持cache isCache: true, // 通过action锁定请求、多个同action不会同时发起请求 isLock: true, // 最小化options回填,推荐select使用 isMiniBackfill: true, // transform($field, data) { // const field = $field.field; // const remoteConfig = field.remoteConfig; // // console.log('transform', $field, field, remoteConfig); // const options = {}; // data.forEach(item => { // options[item[remoteConfig.valueKey]] = item[remoteConfig.labelKey]; // }); // return options; // }, transform($field, data) { const field = $field.field; const remoteConfig = field.remoteConfig; return data.map(item => ({ label: item[remoteConfig.labelKey], value: item[remoteConfig.valueKey] })); }, /** * @param {*} $field 当前field的实例引用 * @param {*} query 当前搜索参数 * @param {*} isBackfill 是否是触发回填 */ async request($field, query = '') { const field = $field.field; const remoteConfig = field.remoteConfig; const method = remoteConfig.method && remoteConfig.method.toUpperCase(); // 组装请求参数 const params = { url: remoteConfig.action || remoteConfig.url, method: method || 'GET', params: {}, data: {} }; if (query) { if (!method || method === 'GET') { params.params[remoteConfig.queryKey] = query; } else if (httpRequestTypeExcludeGet.indexOf(method) >= 0) { params.data[remoteConfig.queryKey] = query; } } // 深度合并传入的params deepExtend(params.params, remoteConfig.params); deepExtend(params.data, remoteConfig.data); const res = await $field.$ams.request(params); return res; }, /** * @param {*} $field 当前field的实例引用 * @param {*} query 当前搜索参数 * @param {*} isBackfill 是否是触发回填 */ async remoteMethod($field, query = '', isBackfill) { let lockQuery; const nextLockQuery = () => { // console.log('nextLockQuery', lockQuery && lockQuery.query.length); if (lockQuery) { lockQuery.isLocking = false; const nextParmas = lockQuery.query.shift(); if (nextParmas) { // console.log('query:', nextParmas, lockQuery.query.length); $field.field.remoteConfig.remoteMethod.apply(this, nextParmas); } } }; try { const field = $field.field; const remoteConfig = field.remoteConfig; if (remoteConfig.isLock) { lockQuery = lockQuerys[remoteConfig.action]; // console.log(JSON.stringify(lockQuery)); if (lockQuery) { if (lockQuery.isLocking) { // console.log('push to query'); lockQuery.query.push([$field, query, isBackfill]); return; } } else { lockQuery = { isLocking: false, query: [] }; lockQuerys[remoteConfig.action] = lockQuery; } lockQuery.isLocking = true; } const cacheKey = remoteConfig.action; // 当有缓存、是回填、缓存开启才会进入缓存获取 if (remoteConfig.isCache && isBackfill && optionsCache[cacheKey]) { // 命中缓存数据或者是允许空值初始化时 if (query && optionsCache[cacheKey][query] || remoteConfig.isInitEmpty) { // console.log('get options from cache success', remoteConfig.isInitEmpty, optionsCache, remoteConfig.isMiniBackfill, query); // 最小化回填时使用当前值 if (remoteConfig.isMiniBackfill && query) { // $field.$set($field.field.props, 'options', { // [query]: optionsCache[cacheKey][query] // }); $field.$set($field.field.props, 'options', [{ label: query, value: optionsCache[cacheKey][query] }]); return nextLockQuery(); } else { // console.log('no query, remoteConfig.isMiniBackfill'); // $field.$set($field.field.props, 'options', optionsCache[cacheKey]); $field.$set($field.field.props, 'options', Object.keys(optionsCache[cacheKey]).map(field => ({ label: field, value: optionsCache[cacheKey][field] })) ); return nextLockQuery(); } } else { console.log('get options from cache fail'); } } $field.loading = true; const res = await remoteConfig.request.call(this, $field, query, isBackfill); $field.loading = false; let data = get(res.data, remoteConfig.dataPath); let successCode; if (typeof remoteConfig.successCode !== 'undefined') { successCode = remoteConfig.successCode; } else { successCode = this.getConfig('resource.api.successCode'); } if ( res.data.code === successCode && data ) { const options = remoteConfig.transform.call(this, $field, data); const optionsEntity = options.reduce((obj, cur) => Object.assign(obj, { [cur.label]: cur.value }), {}); if (remoteConfig.isCache) { optionsCache[cacheKey] = deepExtend(optionsCache[cacheKey] || {}, optionsEntity); } $field.$set($field.field.props, 'options', options); if (typeof remoteConfig.onSuccess === 'function') { remoteConfig.onSuccess(options, res); } } else { $field.$set($field.field.props, 'options', []); if (typeof remoteConfig.onError === 'function') { remoteConfig.onError(data, res); } } nextLockQuery(); } catch (e) { console.log('remoteMethod error:', e); nextLockQuery(); } } }, props: { filterable: true, remote: true, options: {}, 'remote-method': function(query = '', $field) { // 主动调用时要传入$field vue实例,自动调用时通过$parent引用 $field = $field || this.$parent; const $block = $field.$block; const remoteConfig = $field.field.remoteConfig; if (!$block || !remoteConfig || !remoteConfig.action) { return console.warn('no remote action or $block'); } // 节流控制 if (remoteConfig.debounce) { timer && clearTimeout(timer); timer = setTimeout(function () { remoteConfig.remoteMethod.call($block, $field, query, false); }, remoteConfig.debounce); } else { remoteConfig.remoteMethod.call($block, $field, query, false); } } } };