| 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 | 
|     }, | 
|     area:{ | 
|         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); | 
|         console.log('_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 [] | 
|     } | 
|   } | 
| } |