uni-data-picker.js 12 KB

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