uni-data-picker.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623
  1. export default {
  2. props: {
  3. localdata: {
  4. type: [Array, Object],
  5. default () {
  6. return []
  7. }
  8. },
  9. spaceInfo: {
  10. type: Object,
  11. default () {
  12. return {}
  13. }
  14. },
  15. collection: {
  16. type: String,
  17. default: ''
  18. },
  19. action: {
  20. type: String,
  21. default: ''
  22. },
  23. field: {
  24. type: String,
  25. default: ''
  26. },
  27. orderby: {
  28. type: String,
  29. default: ''
  30. },
  31. where: {
  32. type: [String, Object],
  33. default: ''
  34. },
  35. pageData: {
  36. type: String,
  37. default: 'add'
  38. },
  39. pageCurrent: {
  40. type: Number,
  41. default: 1
  42. },
  43. pageSize: {
  44. type: Number,
  45. default: 500
  46. },
  47. getcount: {
  48. type: [Boolean, String],
  49. default: false
  50. },
  51. getone: {
  52. type: [Boolean, String],
  53. default: false
  54. },
  55. gettree: {
  56. type: [Boolean, String],
  57. default: false
  58. },
  59. manual: {
  60. type: Boolean,
  61. default: false
  62. },
  63. value: {
  64. type: [Array, String, Number],
  65. default () {
  66. return []
  67. }
  68. },
  69. modelValue: {
  70. type: [Array, String, Number],
  71. default () {
  72. return []
  73. }
  74. },
  75. preload: {
  76. type: Boolean,
  77. default: false
  78. },
  79. stepSearh: {
  80. type: Boolean,
  81. default: true
  82. },
  83. selfField: {
  84. type: String,
  85. default: ''
  86. },
  87. parentField: {
  88. type: String,
  89. default: ''
  90. },
  91. multiple: {
  92. type: Boolean,
  93. default: false
  94. },
  95. map: {
  96. type: Object,
  97. default () {
  98. return {
  99. text: "text",
  100. value: "value"
  101. }
  102. }
  103. }
  104. },
  105. data() {
  106. return {
  107. loading: false,
  108. errorMessage: '',
  109. loadMore: {
  110. contentdown: '',
  111. contentrefresh: '',
  112. contentnomore: ''
  113. },
  114. dataList: [],
  115. selected: [],
  116. selectedIndex: 0,
  117. page: {
  118. current: this.pageCurrent,
  119. size: this.pageSize,
  120. count: 0
  121. }
  122. }
  123. },
  124. computed: {
  125. isLocalData() {
  126. return !this.collection.length;
  127. },
  128. isCloudData() {
  129. return this.collection.length > 0;
  130. },
  131. isCloudDataList() {
  132. return (this.isCloudData && (!this.parentField && !this.selfField));
  133. },
  134. isCloudDataTree() {
  135. return (this.isCloudData && this.parentField && this.selfField);
  136. },
  137. dataValue() {
  138. let isModelValue = Array.isArray(this.modelValue) ? (this.modelValue.length > 0) : (this.modelValue !== null ||
  139. this.modelValue !== undefined);
  140. return isModelValue ? this.modelValue : this.value;
  141. },
  142. hasValue() {
  143. if (typeof this.dataValue === 'number') {
  144. return true
  145. }
  146. return (this.dataValue != null) && (this.dataValue.length > 0)
  147. }
  148. },
  149. created() {
  150. this.$watch(() => {
  151. var al = [];
  152. ['pageCurrent',
  153. 'pageSize',
  154. 'spaceInfo',
  155. 'value',
  156. 'modelValue',
  157. 'localdata',
  158. 'collection',
  159. 'action',
  160. 'field',
  161. 'orderby',
  162. 'where',
  163. 'getont',
  164. 'getcount',
  165. 'gettree'
  166. ].forEach(key => {
  167. al.push(this[key])
  168. });
  169. return al
  170. }, (newValue, oldValue) => {
  171. let needReset = false
  172. for (let i = 2; i < newValue.length; i++) {
  173. if (newValue[i] != oldValue[i]) {
  174. needReset = true
  175. break
  176. }
  177. }
  178. if (newValue[0] != oldValue[0]) {
  179. this.page.current = this.pageCurrent
  180. }
  181. this.page.size = this.pageSize
  182. this.onPropsChange()
  183. })
  184. this._treeData = []
  185. },
  186. methods: {
  187. onPropsChange() {
  188. this._treeData = [];
  189. },
  190. // 填充 pickview 数据
  191. async loadData() {
  192. if (this.isLocalData) {
  193. this.loadLocalData();
  194. } else if (this.isCloudDataList) {
  195. this.loadCloudDataList();
  196. } else if (this.isCloudDataTree) {
  197. this.loadCloudDataTree();
  198. }
  199. },
  200. // 加载本地数据
  201. async loadLocalData() {
  202. this._treeData = [];
  203. this._extractTree(this.localdata, this._treeData);
  204. let inputValue = this.dataValue;
  205. if (inputValue === undefined) {
  206. return;
  207. }
  208. if (Array.isArray(inputValue)) {
  209. inputValue = inputValue[inputValue.length - 1];
  210. if (typeof inputValue === 'object' && inputValue[this.map.value]) {
  211. inputValue = inputValue[this.map.value];
  212. }
  213. }
  214. this.selected = this._findNodePath(inputValue, this.localdata);
  215. },
  216. // 加载 Cloud 数据 (单列)
  217. async loadCloudDataList() {
  218. if (this.loading) {
  219. return;
  220. }
  221. this.loading = true;
  222. try {
  223. let response = await this.getCommand();
  224. let responseData = response.result.data;
  225. this._treeData = responseData;
  226. this._updateBindData();
  227. this._updateSelected();
  228. this.onDataChange();
  229. } catch (e) {
  230. this.errorMessage = e;
  231. } finally {
  232. this.loading = false;
  233. }
  234. },
  235. // 加载 Cloud 数据 (树形)
  236. async loadCloudDataTree() {
  237. if (this.loading) {
  238. return;
  239. }
  240. this.loading = true;
  241. try {
  242. let commandOptions = {
  243. field: this._cloudDataPostField(),
  244. where: this._cloudDataTreeWhere()
  245. };
  246. if (this.gettree) {
  247. commandOptions.startwith = `${this.selfField}=='${this.dataValue}'`;
  248. }
  249. let response = await this.getCommand(commandOptions);
  250. let responseData = response.result.data;
  251. this._treeData = responseData;
  252. this._updateBindData();
  253. this._updateSelected();
  254. this.onDataChange();
  255. } catch (e) {
  256. this.errorMessage = e;
  257. } finally {
  258. this.loading = false;
  259. }
  260. },
  261. // 加载 Cloud 数据 (节点)
  262. async loadCloudDataNode(callback) {
  263. if (this.loading) {
  264. return;
  265. }
  266. this.loading = true;
  267. try {
  268. let commandOptions = {
  269. field: this._cloudDataPostField(),
  270. where: this._cloudDataNodeWhere()
  271. };
  272. let response = await this.getCommand(commandOptions);
  273. let responseData = response.result.data;
  274. callback(responseData);
  275. } catch (e) {
  276. this.errorMessage = e;
  277. } finally {
  278. this.loading = false;
  279. }
  280. },
  281. // 回显 Cloud 数据
  282. getCloudDataValue() {
  283. if (this.isCloudDataList) {
  284. return this.getCloudDataListValue();
  285. }
  286. if (this.isCloudDataTree) {
  287. return this.getCloudDataTreeValue();
  288. }
  289. },
  290. // 回显 Cloud 数据 (单列)
  291. getCloudDataListValue() {
  292. // 根据 field's as value标识匹配 where 条件
  293. let where = [];
  294. let whereField = this._getForeignKeyByField();
  295. if (whereField) {
  296. where.push(`${whereField} == '${this.dataValue}'`)
  297. }
  298. where = where.join(' || ');
  299. if (this.where) {
  300. where = `(${this.where}) && (${where})`
  301. }
  302. return this.getCommand({
  303. field: this._cloudDataPostField(),
  304. where
  305. }).then((res) => {
  306. this.selected = res.result.data;
  307. return res.result.data;
  308. });
  309. },
  310. // 回显 Cloud 数据 (树形)
  311. getCloudDataTreeValue() {
  312. return this.getCommand({
  313. field: this._cloudDataPostField(),
  314. getTreePath: {
  315. startWith: `${this.selfField}=='${this.dataValue}'`
  316. }
  317. }).then((res) => {
  318. let treePath = [];
  319. this._extractTreePath(res.result.data, treePath);
  320. this.selected = treePath;
  321. return treePath;
  322. });
  323. },
  324. getCommand(options = {}) {
  325. /* eslint-disable no-undef */
  326. let db = uniCloud.database(this.spaceInfo)
  327. const action = options.action || this.action
  328. if (action) {
  329. db = db.action(action)
  330. }
  331. const collection = options.collection || this.collection
  332. db = db.collection(collection)
  333. const where = options.where || this.where
  334. if (!(!where || !Object.keys(where).length)) {
  335. db = db.where(where)
  336. }
  337. const field = options.field || this.field
  338. if (field) {
  339. db = db.field(field)
  340. }
  341. const orderby = options.orderby || this.orderby
  342. if (orderby) {
  343. db = db.orderBy(orderby)
  344. }
  345. const current = options.pageCurrent !== undefined ? options.pageCurrent : this.page.current
  346. const size = options.pageSize !== undefined ? options.pageSize : this.page.size
  347. const getCount = options.getcount !== undefined ? options.getcount : this.getcount
  348. const getTree = options.gettree !== undefined ? options.gettree : this.gettree
  349. const getOptions = {
  350. getCount,
  351. getTree
  352. }
  353. if (options.getTreePath) {
  354. getOptions.getTreePath = options.getTreePath
  355. }
  356. db = db.skip(size * (current - 1)).limit(size).get(getOptions)
  357. return db
  358. },
  359. _cloudDataPostField() {
  360. let fields = [this.field];
  361. if (this.parentField) {
  362. fields.push(`${this.parentField} as parent_value`);
  363. }
  364. return fields.join(',');
  365. },
  366. _cloudDataTreeWhere() {
  367. let result = []
  368. let selected = this.selected
  369. let parentField = this.parentField
  370. if (parentField) {
  371. result.push(`${parentField} == null || ${parentField} == ""`)
  372. }
  373. if (selected.length) {
  374. for (var i = 0; i < selected.length - 1; i++) {
  375. result.push(`${parentField} == '${selected[i].value}'`)
  376. }
  377. }
  378. let where = []
  379. if (this.where) {
  380. where.push(`(${this.where})`)
  381. }
  382. if (result.length) {
  383. where.push(`(${result.join(' || ')})`)
  384. }
  385. return where.join(' && ')
  386. },
  387. _cloudDataNodeWhere() {
  388. let where = []
  389. let selected = this.selected;
  390. if (selected.length) {
  391. where.push(`${this.parentField} == '${selected[selected.length - 1].value}'`);
  392. }
  393. where = where.join(' || ');
  394. if (this.where) {
  395. return `(${this.where}) && (${where})`
  396. }
  397. return where
  398. },
  399. _getWhereByForeignKey() {
  400. let result = []
  401. let whereField = this._getForeignKeyByField();
  402. if (whereField) {
  403. result.push(`${whereField} == '${this.dataValue}'`)
  404. }
  405. if (this.where) {
  406. return `(${this.where}) && (${result.join(' || ')})`
  407. }
  408. return result.join(' || ')
  409. },
  410. _getForeignKeyByField() {
  411. let fields = this.field.split(',');
  412. let whereField = null;
  413. for (let i = 0; i < fields.length; i++) {
  414. const items = fields[i].split('as');
  415. if (items.length < 2) {
  416. continue;
  417. }
  418. if (items[1].trim() === 'value') {
  419. whereField = items[0].trim();
  420. break;
  421. }
  422. }
  423. return whereField;
  424. },
  425. _updateBindData(node) {
  426. const {
  427. dataList,
  428. hasNodes
  429. } = this._filterData(this._treeData, this.selected)
  430. let isleaf = this._stepSearh === false && !hasNodes
  431. if (node) {
  432. node.isleaf = isleaf
  433. }
  434. this.dataList = dataList
  435. this.selectedIndex = dataList.length - 1
  436. if (!isleaf && this.selected.length < dataList.length) {
  437. this.selected.push({
  438. value: null,
  439. text: "请选择"
  440. })
  441. }
  442. return {
  443. isleaf,
  444. hasNodes
  445. }
  446. },
  447. _updateSelected() {
  448. let dl = this.dataList
  449. let sl = this.selected
  450. let textField = this.map.text
  451. let valueField = this.map.value
  452. for (let i = 0; i < sl.length; i++) {
  453. let value = sl[i].value
  454. let dl2 = dl[i]
  455. for (let j = 0; j < dl2.length; j++) {
  456. let item2 = dl2[j]
  457. if (item2[valueField] === value) {
  458. sl[i].text = item2[textField]
  459. break
  460. }
  461. }
  462. }
  463. },
  464. _filterData(data, paths) {
  465. let dataList = []
  466. let hasNodes = true
  467. dataList.push(data.filter((item) => {
  468. return (item.parent_value === null || item.parent_value === undefined || item.parent_value === '')
  469. }))
  470. for (let i = 0; i < paths.length; i++) {
  471. let value = paths[i].value
  472. let nodes = data.filter((item) => {
  473. return item.parent_value === value
  474. })
  475. if (nodes.length) {
  476. dataList.push(nodes)
  477. } else {
  478. hasNodes = false
  479. }
  480. }
  481. return {
  482. dataList,
  483. hasNodes
  484. }
  485. },
  486. _extractTree(nodes, result, parent_value) {
  487. let list = result || []
  488. let valueField = this.map.value
  489. for (let i = 0; i < nodes.length; i++) {
  490. let node = nodes[i]
  491. let child = {}
  492. for (let key in node) {
  493. if (key !== 'children') {
  494. child[key] = node[key]
  495. }
  496. }
  497. if (parent_value !== null && parent_value !== undefined && parent_value !== '') {
  498. child.parent_value = parent_value
  499. }
  500. result.push(child)
  501. let children = node.children
  502. if (children) {
  503. this._extractTree(children, result, node[valueField])
  504. }
  505. }
  506. },
  507. _extractTreePath(nodes, result) {
  508. let list = result || []
  509. for (let i = 0; i < nodes.length; i++) {
  510. let node = nodes[i]
  511. let child = {}
  512. for (let key in node) {
  513. if (key !== 'children') {
  514. child[key] = node[key]
  515. }
  516. }
  517. result.push(child)
  518. let children = node.children
  519. if (children) {
  520. this._extractTreePath(children, result)
  521. }
  522. }
  523. },
  524. _findNodePath(key, nodes, path = []) {
  525. let textField = this.map.text
  526. let valueField = this.map.value
  527. for (let i = 0; i < nodes.length; i++) {
  528. let node = nodes[i]
  529. let children = node.children
  530. let text = node[textField]
  531. let value = node[valueField]
  532. path.push({
  533. value,
  534. text
  535. })
  536. if (value === key) {
  537. return path
  538. }
  539. if (children) {
  540. const p = this._findNodePath(key, children, path)
  541. if (p.length) {
  542. return p
  543. }
  544. }
  545. path.pop()
  546. }
  547. return []
  548. }
  549. }
  550. }