uni-data-picker.js 13 KB

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