CityCascader.vue 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. <template>
  2. <a-cascader
  3. :options="options"
  4. :load-data="loadData"
  5. placeholder="请选择所在区域"
  6. :change-on-select="false"
  7. :default-value="defaultValueCascader"
  8. :fieldNames="fieldNames"
  9. v-model="defaultValueCascader"
  10. @change="onChange"
  11. />
  12. </template>
  13. <script>
  14. import { axios } from '@/utils/request'
  15. import pick from 'lodash.pick'
  16. /**
  17. * 不支持defaultValue 支持initialValue 支持value
  18. */
  19. export default {
  20. name: 'CityCascader',
  21. props: {
  22. placeholder: { // 按钮显示文本
  23. type: String,
  24. default: ''
  25. },
  26. changeOnSelect: {
  27. type: Boolean,
  28. default: false
  29. },
  30. // 被选择的对象,修改的时候需要传参
  31. // regionCode: {
  32. // type: String,
  33. // default: '0'
  34. // },
  35. // eslint-disable-next-line vue/require-default-prop
  36. defaultValue: [String, Number],
  37. // eslint-disable-next-line vue/require-default-prop
  38. value: [String, Number],
  39. // 是否加载树形结构,修改的时候需要传擦
  40. showParent: {
  41. type: Boolean,
  42. default: true
  43. },
  44. // 最大层级 从0开始
  45. maxLevel: {
  46. type: Number,
  47. default: 3
  48. },
  49. fieldNames: {
  50. type: Object,
  51. default: () => ({
  52. label: 'name',
  53. value: 'regionCode',
  54. fullName: 'fullName',
  55. children: 'children',
  56. level: 'level'
  57. })
  58. }
  59. },
  60. data () {
  61. return {
  62. defaultValueCascader: [],
  63. regionCode: '0',
  64. options: [],
  65. isInit: true
  66. }
  67. },
  68. watch: {
  69. regionCode: function (val, oldVal) {
  70. this.reloadData(val, true)
  71. },
  72. value: function (val, oldVal) {
  73. this.regionCode = this.BaseTool.Object.isNotBlank(val) ? val : (this.defaultValue | '0')
  74. }
  75. },
  76. created () {
  77. if (this.BaseTool.Object.isNotBlank(this.value)) {
  78. this.reloadData(this.value, false)
  79. } else {
  80. this.reloadData(this.regionCode, false)
  81. }
  82. },
  83. methods: {
  84. async reloadData (val, isWitch) {
  85. if (isWitch) {
  86. this.isInit = false
  87. }
  88. if (!isWitch && !this.isInit) {
  89. return
  90. }
  91. if (this.showParent) {
  92. if (this.BaseTool.String.isNotBlank(val) && val !== '0') {
  93. if (val.length >= 12) {
  94. this.defaultValueCascader = [val.substr(0, 2), val.substr(0, 4), val.substr(0, 6), val.substr(0, 9), val.substr(0, 12)]
  95. } else if (val.length >= 9) {
  96. this.defaultValueCascader = [val.substr(0, 2), val.substr(0, 4), val.substr(0, 6), val.substr(0, 9)]
  97. } else if (val.length >= 6) {
  98. this.defaultValueCascader = [val.substr(0, 2), val.substr(0, 4), val.substr(0, 6)]
  99. } else if (val.length >= 4) {
  100. this.defaultValueCascader = [val.substr(0, 2), val.substr(0, 4)]
  101. } else if (val.length >= 2) {
  102. this.defaultValueCascader = [val.substr(0, 2)]
  103. } else {
  104. this.defaultValueCascader = []
  105. }
  106. } else {
  107. this.defaultValueCascader = []
  108. }
  109. }
  110. if (this.showParent && val !== '0') {
  111. const d = await this.treeBaseVOCityInfo({ regionCode: val })
  112. if (!isWitch && !this.isInit) {
  113. } else {
  114. this.options = this.treeDataToOptions(d.data.children)
  115. }
  116. } else {
  117. const d = await this.baseVOCityInfo({ parentId: val })
  118. if (!isWitch && !this.isInit) {
  119. } else {
  120. this.options = this.dataToOptions(d.data.children)
  121. }
  122. }
  123. },
  124. loadData: function (selectedOptions) {
  125. const parentVO = selectedOptions[selectedOptions.length - 1]
  126. parentVO.loading = true
  127. // 获取主键
  128. const regionCode = parentVO[this.fieldNames.value]
  129. this.baseVOCityInfo({ parentId: regionCode }).then((res) => {
  130. parentVO.loading = false
  131. parentVO.children = this.dataToOptions(res.data.children)
  132. this.options = [...this.options]
  133. })
  134. },
  135. treeDataToOptions: function (data) {
  136. for (let i = 0; i < data.length; i++) {
  137. if (data[i].isSelect) {
  138. data[i] = this.dataToData(data[i])
  139. } else {
  140. data[i] = Object.assign(pick(data[i], [
  141. this.fieldNames.value,
  142. this.fieldNames.fullName,
  143. this.fieldNames.label,
  144. this.fieldNames.level
  145. ]))
  146. }
  147. data[i].isLeaf = data[i][this.fieldNames.level] >= this.maxLevel
  148. }
  149. return data
  150. },
  151. dataToData (data) {
  152. const isLeaf = data[this.fieldNames.level] >= this.maxLevel
  153. if (isLeaf) {
  154. return Object.assign(pick(data, [
  155. this.fieldNames.value,
  156. this.fieldNames.fullName,
  157. this.fieldNames.label,
  158. this.fieldNames.level
  159. ]))
  160. }
  161. const d = Object.assign(pick(data, [
  162. this.fieldNames.value,
  163. this.fieldNames.fullName,
  164. this.fieldNames.label,
  165. this.fieldNames.level
  166. ]))
  167. if (data.isSelect) {
  168. d.children = []
  169. for (let i = 0; i < data.children.length; i++) {
  170. d.children.push(this.dataToData(data.children[i]))
  171. }
  172. } else {
  173. d.isLeaf = d[this.fieldNames.level] >= this.maxLevel
  174. }
  175. return d
  176. },
  177. dataToOptions: function (data) {
  178. for (let i = 0; i < data.length; i++) {
  179. data[i] = Object.assign(pick(data[i], [
  180. this.fieldNames.value,
  181. this.fieldNames.fullName,
  182. this.fieldNames.label,
  183. this.fieldNames.level
  184. ]))
  185. data[i].isLeaf = data[i][this.fieldNames.level] >= this.maxLevel
  186. }
  187. return data
  188. },
  189. onChange (value, selectedOptions) {
  190. if (this.BaseTool.Object.isBlank(selectedOptions) || !selectedOptions.length) {
  191. this.defaultValueCascader = null
  192. this.$emit('change', null, {})
  193. return
  194. }
  195. const v = selectedOptions[selectedOptions.length - 1]
  196. this.$emit('change', v[this.fieldNames.value], v)
  197. },
  198. baseVOCityInfo: function (parameter) {
  199. return axios({
  200. url: `/city/infos/base/${parameter.parentId}`,
  201. method: 'get',
  202. headers: {
  203. 'Content-Type': 'application/json;charset=UTF-8'
  204. }
  205. })
  206. },
  207. treeBaseVOCityInfo: function (parameter) {
  208. return axios({
  209. url: `/city/infos/base/tree/${parameter.regionCode}`,
  210. method: 'get',
  211. headers: {
  212. 'Content-Type': 'application/json;charset=UTF-8'
  213. }
  214. })
  215. }
  216. },
  217. updated: function () {
  218. }
  219. }
  220. </script>
  221. <style scoped>
  222. </style>