JVxeSelectDictSearchCell.js 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. import debounce from 'lodash/debounce'
  2. import { getAction } from '@/api/manage'
  3. import { cloneObject } from '@/utils/util'
  4. import { filterDictText } from '@/components/dict/JDictSelectUtil'
  5. import { ajaxGetDictItems, getDictItemsFromCache } from '@/api/api'
  6. import JVxeCellMixins, { dispatchEvent } from '@/components/jeecg/JVxeTable/mixins/JVxeCellMixins'
  7. /** 公共资源 */
  8. const common = {
  9. /** value - label map,防止重复查询(刷新清空缓存) */
  10. labelMap: new Map(),
  11. /** 公共data */
  12. data() {
  13. return {
  14. loading: false,
  15. innerSelectValue: null,
  16. innerOptions: [],
  17. }
  18. },
  19. /** 公共计算属性 */
  20. computed: {
  21. dict() {
  22. return this.originColumn.dict
  23. },
  24. options() {
  25. if (this.isAsync) {
  26. return this.innerOptions
  27. } else {
  28. return this.originColumn.options || []
  29. }
  30. },
  31. // 是否是异步模式
  32. isAsync() {
  33. let isAsync = this.originColumn.async
  34. return (isAsync != null && isAsync !== '') ? !!isAsync : true
  35. },
  36. },
  37. /** 公共属性监听 */
  38. watch: {
  39. innerValue: {
  40. immediate: true,
  41. handler(value) {
  42. if (value == null || value === '') {
  43. this.innerSelectValue = null
  44. } else {
  45. this.loadDataByValue(value)
  46. }
  47. }
  48. },
  49. dict() {
  50. this.loadDataByDict()
  51. }
  52. },
  53. /** 公共方法 */
  54. methods: {
  55. // 根据 value 查询数据,用于回显
  56. async loadDataByValue(value) {
  57. if (this.isAsync) {
  58. if (this.innerSelectValue !== value) {
  59. if (common.labelMap.has(value)) {
  60. this.innerOptions = cloneObject(common.labelMap.get(value))
  61. } else {
  62. let {success, result} = await getAction(`/sys/dict/loadDictItem/${this.dict}`, {key: value})
  63. if (success && result && result.length > 0) {
  64. this.innerOptions = [{value: value, text: result[0]}]
  65. common.labelMap.set(value, cloneObject(this.innerOptions))
  66. }
  67. }
  68. }
  69. }
  70. this.innerSelectValue = (value || '').toString()
  71. },
  72. // 初始化字典
  73. async loadDataByDict() {
  74. if (!this.isAsync) {
  75. // 如果字典项集合有数据
  76. if (!this.originColumn.options || this.originColumn.options.length === 0) {
  77. // 根据字典Code, 初始化字典数组
  78. let dictStr = ''
  79. if (this.dict) {
  80. let arr = this.dict.split(',')
  81. if (arr[0].indexOf('where') > 0) {
  82. let tbInfo = arr[0].split('where')
  83. dictStr = tbInfo[0].trim() + ',' + arr[1] + ',' + arr[2] + ',' + encodeURIComponent(tbInfo[1])
  84. } else {
  85. dictStr = this.dict
  86. }
  87. if (this.dict.indexOf(',') === -1) {
  88. //优先从缓存中读取字典配置
  89. let cache = getDictItemsFromCache(this.dict)
  90. if (cache) {
  91. this.innerOptions = cache
  92. return
  93. }
  94. }
  95. let {success, result} = await ajaxGetDictItems(dictStr, null)
  96. if (success) {
  97. this.innerOptions = result
  98. }
  99. }
  100. }
  101. }
  102. },
  103. },
  104. }
  105. // 显示组件,自带翻译
  106. export const DictSearchSpanCell = {
  107. name: 'JVxeSelectSearchSpanCell',
  108. mixins: [JVxeCellMixins],
  109. data() {
  110. return {
  111. ...common.data.apply(this),
  112. }
  113. },
  114. computed: {
  115. ...common.computed,
  116. },
  117. watch: {
  118. ...common.watch,
  119. },
  120. methods: {
  121. ...common.methods,
  122. },
  123. render(h) {
  124. return h('span', {}, [
  125. filterDictText(this.innerOptions, this.innerSelectValue || this.innerValue)
  126. ])
  127. },
  128. }
  129. // 请求id
  130. let requestId = 0
  131. // 输入选择组件
  132. export const DictSearchInputCell = {
  133. name: 'JVxeSelectSearchInputCell',
  134. mixins: [JVxeCellMixins],
  135. data() {
  136. return {
  137. ...common.data.apply(this),
  138. hasRequest: false,
  139. scopedSlots: {
  140. notFoundContent: () => {
  141. if (this.loading) {
  142. return <a-spin size="small"/>
  143. } else if (this.hasRequest) {
  144. return <div>没有查询到任何数据</div>
  145. } else {
  146. return <div>{this.tipsContent}</div>
  147. }
  148. }
  149. }
  150. }
  151. },
  152. computed: {
  153. ...common.computed,
  154. tipsContent() {
  155. return this.originColumn.tipsContent || '请输入搜索内容'
  156. },
  157. filterOption() {
  158. if (this.isAsync) {
  159. return null
  160. }
  161. return (input, option) => option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
  162. },
  163. },
  164. watch: {
  165. ...common.watch,
  166. },
  167. created() {
  168. this.loadData = debounce(this.loadData, 300)//消抖
  169. },
  170. methods: {
  171. ...common.methods,
  172. loadData(value) {
  173. const currentRequestId = ++requestId
  174. this.loading = true
  175. this.innerOptions = []
  176. if (value == null || value.trim() === '') {
  177. this.loading = false
  178. this.hasRequest = false
  179. return
  180. }
  181. // 字典code格式:table,text,code
  182. this.hasRequest = true
  183. getAction(`/sys/dict/loadDict/${this.dict}`, {keyword: value}).then(res => {
  184. if (currentRequestId !== requestId) {
  185. return
  186. }
  187. let {success, result, message} = res
  188. if (success) {
  189. this.innerOptions = result
  190. result.forEach((item) => {
  191. common.labelMap.set(item.value, [item])
  192. })
  193. } else {
  194. this.$message.warning(message)
  195. }
  196. }).finally(() => {
  197. this.loading = false
  198. })
  199. },
  200. handleChange(selectedValue) {
  201. this.innerSelectValue = selectedValue
  202. this.handleChangeCommon(this.innerSelectValue)
  203. },
  204. handleSearch(value) {
  205. if (this.isAsync) {
  206. // 在输入时也应该开启加载,因为loadData加了消抖,所以会有800ms的用户主观上认为的卡顿时间
  207. this.loading = true
  208. if (this.innerOptions.length > 0) {
  209. this.innerOptions = []
  210. }
  211. this.loadData(value)
  212. }
  213. },
  214. renderOptionItem() {
  215. let options = []
  216. this.options.forEach(({value, text, label, title, disabled}) => {
  217. options.push(
  218. <a-select-option key={value} value={value} disabled={disabled}>{text || label || title}</a-select-option>
  219. )
  220. })
  221. return options
  222. },
  223. },
  224. render() {
  225. return (
  226. <a-select
  227. showSearch
  228. allowClear
  229. value={this.innerSelectValue}
  230. filterOption={this.filterOption}
  231. style="width: 100%"
  232. {...this.cellProps}
  233. onSearch={this.handleSearch}
  234. onChange={this.handleChange}
  235. scopedSlots={this.scopedSlots}
  236. >
  237. {this.renderOptionItem()}
  238. </a-select>
  239. )
  240. },
  241. // 【组件增强】注释详见:JVxeCellMixins.js
  242. enhanced: {
  243. aopEvents: {
  244. editActived(event) {
  245. dispatchEvent.call(this, event, 'ant-select')
  246. },
  247. },
  248. }
  249. }