index.jsx 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. import { h, defineComponent, computed, ref } from 'vue'
  2. import { ElForm, ElFormItem } from 'element-plus'
  3. import { ArrowUp, ArrowDown } from '@element-plus/icons-vue'
  4. import CipButton from '../cip-button'
  5. import CipFormItem from '../cip-form-item'
  6. import { debounce, isNumber, getUsingConfig } from '@cip/utils/util'
  7. import { useFormProvide } from '../hooks/use-form'
  8. import { useObserveDomResize } from '../hooks/use-dom-resize'
  9. import { cipSearchFormProps } from './props'
  10. import './index.less'
  11. import { useCipConfig } from '@cip/components/hooks/use-cip-config'
  12. import { usePrivileges } from '@cip/hooks/use-privileges'
  13. import { judgePrivilege } from '@cip/components/cip-judge-privilege/util'
  14. // cip-search-form 强制开启grid模式
  15. export default defineComponent({
  16. name: 'CipSearchForm',
  17. props: cipSearchFormProps,
  18. emits: ['update:model', 'search'],
  19. setup (props, { emit, attrs }) {
  20. useFormProvide(props)
  21. const cipConfig = useCipConfig()
  22. const cipSearchForm = ref()
  23. const contentWidth = ref(1000)
  24. useObserveDomResize(() => cipSearchForm.value.$el, (e) => {
  25. contentWidth.value = e.contentRect.width
  26. })
  27. // 值更新
  28. const updateModel = (val) => { emit('update:model', val) }
  29. // 触发搜索
  30. const emitSearch = debounce((type) => { emit('search', type) }, 200, false)
  31. const resetSearch = () => {
  32. // 重置的时候载入默认model
  33. updateModel({ })
  34. emitSearch('reset')
  35. }
  36. const isExpand = ref(false)
  37. const toggleExpand = () => {
  38. isExpand.value = !isExpand.value
  39. }
  40. // 1366使用3列,1920使用5列,默认4列
  41. const gridCount = computed(() => {
  42. const grid = getUsingConfig(props.grid, cipConfig.searchGrid)
  43. if (isNumber(grid) && grid > 0) return grid // 过滤grid为数字且grid>0 则使用固定的列
  44. return Math.max(2, Math.floor(contentWidth.value / 335)) // contentWidth.value < 1300 ? 3 : (contentWidth.value > 1900 ? 5 : 4)
  45. })
  46. const privileges = usePrivileges()
  47. // 展示数量列表
  48. const fieldShowList = computed(() => {
  49. // 此处未考虑code为数组的情况
  50. const fieldList = props.fieldList.filter(({ key, config = {} }) => judgePrivilege(config.code, privileges.value))
  51. if (!props.collapse) {
  52. return fieldList
  53. } else {
  54. return isExpand.value ? fieldList : fieldList.filter((item, index) => index < gridCount.value - 1)
  55. }
  56. })
  57. const isImmediateSearch = (config) => {
  58. return config.immediateSearch === true || config.autoSelect === true
  59. }
  60. const showResetButton = computed(() => {
  61. return getUsingConfig(props.searchReset, cipConfig.searchReset)
  62. })
  63. const showExpandButton = computed(() => {
  64. return props.collapse && props.fieldList.length >= gridCount.value
  65. })
  66. const arrowIcon = computed(() => {
  67. return isExpand.value ? ArrowUp : ArrowDown
  68. })
  69. const formModel = computed(() => Object.assign({}, props.defaultModel, props.model))
  70. const formItem = ({ key, config } = {}) => {
  71. return h(CipFormItem, {
  72. key,
  73. model: formModel.value,
  74. fieldKey: key,
  75. config: config,
  76. grid: true,
  77. onKeyup: (e) => {
  78. const { keyCode } = e
  79. if (keyCode === 13) {
  80. emitSearch()
  81. }
  82. },
  83. onSearch: () => {
  84. emitSearch()
  85. },
  86. 'onUpdate:model': (val) => {
  87. updateModel(val)
  88. // 值变更时立即搜索
  89. if (isImmediateSearch(config)) emitSearch()
  90. }
  91. })
  92. }
  93. const formItemList = () => fieldShowList.value.map(formItem)
  94. const formDefaultSlots = () => {
  95. const slots = formItemList() || []
  96. // 隐藏搜索按钮 或
  97. // 当搜索条件整行时 且 为展开时
  98. if (!props.hideSearch) {
  99. // 是否仅一个搜索条件
  100. const isOne = fieldShowList.value.length === 1
  101. const buttonList = <ElFormItem class={
  102. [
  103. 'cip-search-button',
  104. {
  105. 'cip-search-button--right': !isOne,
  106. 'cip-search-button--absolute': props.handleAbsolute && isExpand.value && (props.fieldList.length % gridCount.value === 0)
  107. }
  108. ]
  109. }
  110. style={{
  111. alignItems: props.labelPosition === 'top' ? 'flex-end' : 'flex-start',
  112. gridColumn: !isOne ? `${gridCount.value} / span 1` : undefined
  113. }}
  114. >
  115. <CipButton buttonType={'search'} loading={props.listLoading} onClick={() => emitSearch()}>
  116. {{ default: ({ text }) => props.searchButtonText ?? text }}
  117. </CipButton>
  118. {showResetButton.value && <CipButton loading={props.listLoading} buttonType={'reset'} onClick={() => resetSearch()}/>}
  119. {showExpandButton.value && <CipButton square={true} icon={arrowIcon.value} onClick={() => toggleExpand()}/>}
  120. </ElFormItem>
  121. slots.push(buttonList)
  122. }
  123. return slots
  124. }
  125. if (props.hideSearch) { // 一次性配置不进行响应
  126. isExpand.value = true
  127. }
  128. return () => h(ElForm, {
  129. ...attrs,
  130. ref: cipSearchForm,
  131. class: 'cip-search-form',
  132. labelPosition: props.labelPosition,
  133. size: 'default',
  134. style: { gridTemplateColumns: `repeat(${gridCount.value}, 1fr)` },
  135. onSubmit: (e) => {
  136. e.preventDefault()
  137. emitSearch()
  138. } // 防止只有一个搜索项时按会车直接提交form的默认行为
  139. }, { default: formDefaultSlots })
  140. }
  141. })