uni-data-picker.js 13 KB

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