|
|
export default { props: { localdata: { type: [Array, Object], default () { return [] } }, spaceInfo: { type: Object, default () { return {} } }, collection: { type: String, default: '' }, action: { type: String, default: '' }, field: { type: String, default: '' }, orderby: { type: String, default: '' }, where: { type: [String, Object], default: '' }, pageData: { type: String, default: 'add' }, pageCurrent: { type: Number, default: 1 }, pageSize: { type: Number, default: 500 }, getcount: { type: [Boolean, String], default: false }, getone: { type: [Boolean, String], default: false }, gettree: { type: [Boolean, String], default: false }, manual: { type: Boolean, default: false }, value: { type: [Array, String, Number], default () { return [] } }, modelValue: { type: [Array, String, Number], default () { return [] } }, preload: { type: Boolean, default: false }, stepSearh: { type: Boolean, default: true }, selfField: { type: String, default: '' }, parentField: { type: String, default: '' }, multiple: { type: Boolean, default: false }, map: { type: Object, default () { return { text: "text", value: "value" } } } }, data() { return { loading: false, errorMessage: '', loadMore: { contentdown: '', contentrefresh: '', contentnomore: '' }, dataList: [], selected: [], selectedIndex: 0, page: { current: this.pageCurrent, size: this.pageSize, count: 0 } } }, computed: { isLocalData() { return !this.collection.length; }, isCloudData() { return this.collection.length > 0; }, isCloudDataList() { return (this.isCloudData && (!this.parentField && !this.selfField)); }, isCloudDataTree() { return (this.isCloudData && this.parentField && this.selfField); }, dataValue() { let isModelValue = Array.isArray(this.modelValue) ? (this.modelValue.length > 0) : (this.modelValue !== null || this.modelValue !== undefined); return isModelValue ? this.modelValue : this.value; }, hasValue() { if (typeof this.dataValue === 'number') { return true } return (this.dataValue != null) && (this.dataValue.length > 0) } }, created() { this.$watch(() => { var al = []; ['pageCurrent', 'pageSize', 'spaceInfo', 'value', 'modelValue', 'localdata', 'collection', 'action', 'field', 'orderby', 'where', 'getont', 'getcount', 'gettree' ].forEach(key => { al.push(this[key]) }); return al }, (newValue, oldValue) => { let needReset = false for (let i = 2; i < newValue.length; i++) { if (newValue[i] != oldValue[i]) { needReset = true break } } if (newValue[0] != oldValue[0]) { this.page.current = this.pageCurrent } this.page.size = this.pageSize
this.onPropsChange() }) this._treeData = [] }, methods: { onPropsChange() { this._treeData = []; },
// 填充 pickview 数据
async loadData() { if (this.isLocalData) { this.loadLocalData(); } else if (this.isCloudDataList) { this.loadCloudDataList(); } else if (this.isCloudDataTree) { this.loadCloudDataTree(); } },
// 加载本地数据
async loadLocalData() { this._treeData = []; this._extractTree(this.localdata, this._treeData);
let inputValue = this.dataValue; if (inputValue === undefined) { return; }
if (Array.isArray(inputValue)) { inputValue = inputValue[inputValue.length - 1]; if (typeof inputValue === 'object' && inputValue[this.map.value]) { inputValue = inputValue[this.map.value]; } }
this.selected = this._findNodePath(inputValue, this.localdata); },
// 加载 Cloud 数据 (单列)
async loadCloudDataList() { if (this.loading) { return; } this.loading = true;
try { let response = await this.getCommand(); let responseData = response.result.data;
this._treeData = responseData;
this._updateBindData(); this._updateSelected();
this.onDataChange(); } catch (e) { this.errorMessage = e; } finally { this.loading = false; } },
// 加载 Cloud 数据 (树形)
async loadCloudDataTree() { if (this.loading) { return; } this.loading = true;
try { let commandOptions = { field: this._cloudDataPostField(), where: this._cloudDataTreeWhere() }; if (this.gettree) { commandOptions.startwith = `${this.selfField}=='${this.dataValue}'`; }
let response = await this.getCommand(commandOptions); let responseData = response.result.data;
this._treeData = responseData; this._updateBindData(); this._updateSelected();
this.onDataChange(); } catch (e) { this.errorMessage = e; } finally { this.loading = false; } },
// 加载 Cloud 数据 (节点)
async loadCloudDataNode(callback) { if (this.loading) { return; } this.loading = true;
try { let commandOptions = { field: this._cloudDataPostField(), where: this._cloudDataNodeWhere() };
let response = await this.getCommand(commandOptions); let responseData = response.result.data;
callback(responseData); } catch (e) { this.errorMessage = e; } finally { this.loading = false; } },
// 回显 Cloud 数据
getCloudDataValue() { if (this.isCloudDataList) { return this.getCloudDataListValue(); }
if (this.isCloudDataTree) { return this.getCloudDataTreeValue(); } },
// 回显 Cloud 数据 (单列)
getCloudDataListValue() { // 根据 field's as value标识匹配 where 条件
let where = []; let whereField = this._getForeignKeyByField(); if (whereField) { where.push(`${whereField} == '${this.dataValue}'`) }
where = where.join(' || ');
if (this.where) { where = `(${this.where}) && (${where})` }
return this.getCommand({ field: this._cloudDataPostField(), where }).then((res) => { this.selected = res.result.data; return res.result.data; }); },
// 回显 Cloud 数据 (树形)
getCloudDataTreeValue() { return this.getCommand({ field: this._cloudDataPostField(), getTreePath: { startWith: `${this.selfField}=='${this.dataValue}'` } }).then((res) => { let treePath = []; this._extractTreePath(res.result.data, treePath); this.selected = treePath; return treePath; }); },
getCommand(options = {}) { /* eslint-disable no-undef */ let db = uniCloud.database(this.spaceInfo)
const action = options.action || this.action if (action) { db = db.action(action) }
const collection = options.collection || this.collection db = db.collection(collection)
const where = options.where || this.where if (!(!where || !Object.keys(where).length)) { db = db.where(where) }
const field = options.field || this.field if (field) { db = db.field(field) }
const orderby = options.orderby || this.orderby if (orderby) { db = db.orderBy(orderby) }
const current = options.pageCurrent !== undefined ? options.pageCurrent : this.page.current const size = options.pageSize !== undefined ? options.pageSize : this.page.size const getCount = options.getcount !== undefined ? options.getcount : this.getcount const getTree = options.gettree !== undefined ? options.gettree : this.gettree
const getOptions = { getCount, getTree } if (options.getTreePath) { getOptions.getTreePath = options.getTreePath }
db = db.skip(size * (current - 1)).limit(size).get(getOptions)
return db },
_cloudDataPostField() { let fields = [this.field]; if (this.parentField) { fields.push(`${this.parentField} as parent_value`); } return fields.join(','); },
_cloudDataTreeWhere() { let result = [] let selected = this.selected let parentField = this.parentField if (parentField) { result.push(`${parentField} == null || ${parentField} == ""`) } if (selected.length) { for (var i = 0; i < selected.length - 1; i++) { result.push(`${parentField} == '${selected[i].value}'`) } }
let where = [] if (this.where) { where.push(`(${this.where})`) }
if (result.length) { where.push(`(${result.join(' || ')})`) }
return where.join(' && ') },
_cloudDataNodeWhere() { let where = [] let selected = this.selected; if (selected.length) { where.push(`${this.parentField} == '${selected[selected.length - 1].value}'`); }
where = where.join(' || ');
if (this.where) { return `(${this.where}) && (${where})` }
return where },
_getWhereByForeignKey() { let result = [] let whereField = this._getForeignKeyByField(); if (whereField) { result.push(`${whereField} == '${this.dataValue}'`) }
if (this.where) { return `(${this.where}) && (${result.join(' || ')})` }
return result.join(' || ') },
_getForeignKeyByField() { let fields = this.field.split(','); let whereField = null; for (let i = 0; i < fields.length; i++) { const items = fields[i].split('as'); if (items.length < 2) { continue; } if (items[1].trim() === 'value') { whereField = items[0].trim(); break; } } return whereField; },
_updateBindData(node) { const { dataList, hasNodes } = this._filterData(this._treeData, this.selected)
let isleaf = this._stepSearh === false && !hasNodes
if (node) { node.isleaf = isleaf }
this.dataList = dataList this.selectedIndex = dataList.length - 1
if (!isleaf && this.selected.length < dataList.length) { this.selected.push({ value: null, text: "请选择" }) }
return { isleaf, hasNodes } },
_updateSelected() { let dl = this.dataList let sl = this.selected let textField = this.map.text let valueField = this.map.value for (let i = 0; i < sl.length; i++) { let value = sl[i].value let dl2 = dl[i] for (let j = 0; j < dl2.length; j++) { let item2 = dl2[j] if (item2[valueField] === value) { sl[i].text = item2[textField] break } } } },
_filterData(data, paths) { let dataList = [] let hasNodes = true
dataList.push(data.filter((item) => { return (item.parent_value === null || item.parent_value === undefined || item.parent_value === '') })) for (let i = 0; i < paths.length; i++) { let value = paths[i].value let nodes = data.filter((item) => { return item.parent_value === value })
if (nodes.length) { dataList.push(nodes) } else { hasNodes = false } }
return { dataList, hasNodes } },
_extractTree(nodes, result, parent_value) { let list = result || [] let valueField = this.map.value for (let i = 0; i < nodes.length; i++) { let node = nodes[i]
let child = {} for (let key in node) { if (key !== 'children') { child[key] = node[key] } } if (parent_value !== null && parent_value !== undefined && parent_value !== '') { child.parent_value = parent_value } result.push(child)
let children = node.children if (children) { this._extractTree(children, result, node[valueField]) } } },
_extractTreePath(nodes, result) { let list = result || [] for (let i = 0; i < nodes.length; i++) { let node = nodes[i]
let child = {} for (let key in node) { if (key !== 'children') { child[key] = node[key] } } result.push(child)
let children = node.children if (children) { this._extractTreePath(children, result) } } },
_findNodePath(key, nodes, path = []) { let textField = this.map.text let valueField = this.map.value for (let i = 0; i < nodes.length; i++) { let node = nodes[i] let children = node.children let text = node[textField] let value = node[valueField]
path.push({ value, text })
if (value === key) { return path }
if (children) { const p = this._findNodePath(key, children, path) if (p.length) { return p } }
path.pop() } return [] } } }
|