index.vue 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. <template>
  2. <div :style="{width}">
  3. <!--输入框-->
  4. <template v-if="!securityConfig.trigger">
  5. <el-input :placeholder="config.placeholder" readonly v-bind="$attrs" :model-value="proxyOtherValue[0].value || modelValue" :style="{width: config.width || '100%'}" :disabled="disabled" @click="openDialog">
  6. <template #append>
  7. <cip-button :square="true" :icon="Search" :disabled="disabled" @click="openDialog"/>
  8. </template>
  9. </el-input>
  10. </template>
  11. <!--按钮模式-->
  12. <template v-if="securityConfig.trigger === 'button'">
  13. <cip-button type="primary" :disabled="disabled" @click="openDialog">选择({{multiple && (defaultValue?.length || 0)}})</cip-button>
  14. </template>
  15. <!--选择弹窗-->
  16. <cip-dialog
  17. v-model="tableDialog"
  18. :title="`选择${config.label}`"
  19. class="select-input__dialog"
  20. top="6vh"
  21. :on-confirm="onConfirm">
  22. <cip-select-table
  23. style="width: 100%"
  24. v-bind="selectTableProps"
  25. :multiple="multiple"
  26. v-model="cacheSelectItem"
  27. />
  28. </cip-dialog>
  29. </div>
  30. </template>
  31. <script>
  32. import { computed, ref } from 'vue'
  33. import { ElInput } from 'element-plus'
  34. import { Search } from '@element-plus/icons-vue'
  35. import CipDialog from '@cip/components/cip-dialog'
  36. import CipButton from '@cip/components/cip-button'
  37. import CipSelectTable from '@cip/components/cip-select-table'
  38. import CipMessage from '@cip/components/cip-message'
  39. import { formInputProps, fromInputEmits, useFormInput, useInputProps } from '@cip/components/helper/form-input'
  40. import { isArray, isNotEmpty } from '@cip/utils/util'
  41. export default {
  42. components: { ElInput, CipDialog, CipButton, CipSelectTable },
  43. props: formInputProps,
  44. emits: fromInputEmits,
  45. setup (props, context) {
  46. // 转换较为复杂,放弃使用formInput提供的fromModelValue及toModelValue进行modelValue的转换
  47. const {
  48. emitInput,
  49. emitOtherValue,
  50. proxyOtherValue,
  51. securityConfig,
  52. updateStream,
  53. ...formInput
  54. } = useFormInput(props, context, {
  55. fromModelValue: () => {},
  56. maxOtherKey: 2
  57. })
  58. const multiple = computed(() => {
  59. return securityConfig.value.multiple ?? false
  60. })
  61. const optionProps = computed(() => {
  62. return Object.assign({},
  63. { label: 'label', value: 'value' },
  64. securityConfig.value.defaultProp, // 兼容历史数据
  65. securityConfig.value.optionProps
  66. )
  67. })
  68. // cip-select-table的配置
  69. const selectTableProps = useInputProps(props, [
  70. 'direction',
  71. 'multiple',
  72. 'entity',
  73. 'curdFn',
  74. 'tableColumns',
  75. 'searchFieldList',
  76. 'optionProps',
  77. 'hideSearch',
  78. 'defaultSearchModel',
  79. 'withPagination',
  80. 'selectable',
  81. ['tableHideIndex', 'hideIndex'],
  82. ['defaultSearchFilter', 'defaultSearchModel'],
  83. 'withTags'
  84. ])
  85. const tableDialog = ref(false)
  86. const cacheSelectItem = ref()
  87. // 打开选择弹框
  88. const openDialog = () => {
  89. if (defaultValue.value) {
  90. // 进行一次浅拷贝,防止修改数据导致值直接变化
  91. cacheSelectItem.value = multiple.value ? [...defaultValue.value] : { ...defaultValue.value }
  92. } else {
  93. // 清理上一次的选中结果
  94. cacheSelectItem.value = multiple.value ? [] : undefined
  95. }
  96. tableDialog.value = true
  97. }
  98. // 获取emit需要的值
  99. const getEmitValue = (type) => { // {'value'| 'label'}
  100. const rows = cacheSelectItem.value
  101. if (multiple.value) {
  102. let modelValue = rows.map(i => i[optionProps.value[type]])
  103. if (!securityConfig.value.array) {
  104. modelValue = modelValue.join(',')
  105. }
  106. return modelValue
  107. } else {
  108. return rows[optionProps.value[type]]
  109. }
  110. }
  111. // 确认保存
  112. const onConfirm = async (resolve, reject) => {
  113. if (securityConfig.value.validate) {
  114. const { valid, message = '校验失败' } = await securityConfig.value.validate?.(cacheSelectItem.value)
  115. if (!valid) {
  116. CipMessage.warning(message)
  117. reject()
  118. }
  119. }
  120. const value = getEmitValue('value')
  121. const label = getEmitValue('label')
  122. updateStream.appendValue(value)
  123. updateStream.appendOtherValue(label)
  124. updateStream.appendOtherValue(cacheSelectItem.value, 2)
  125. updateStream.end()
  126. resolve()
  127. }
  128. const fromModel = (val) => {
  129. const result = []
  130. if (val) {
  131. if (isArray(val)) {
  132. return val
  133. } else {
  134. return val.split(',')
  135. }
  136. }
  137. return result
  138. }
  139. // 选择table组件
  140. const defaultValue = computed(() => {
  141. if (isNotEmpty(props.modelValue)) {
  142. if (multiple.value) {
  143. if (proxyOtherValue[1].value) return proxyOtherValue[1].value
  144. let code = fromModel(props.modelValue)
  145. if (securityConfig.value.valueType === 'number') code = code.map(v => Number(v))
  146. const name = fromModel(proxyOtherValue[0].value) // 没有这个数据怎么办
  147. return code.map((i, idx) => ({
  148. [optionProps.value.value]: i,
  149. [optionProps.value.label]: name[idx]
  150. }))
  151. } else {
  152. return {
  153. [optionProps.value.value]: props.modelValue,
  154. [optionProps.value.label]: proxyOtherValue[0].value
  155. }
  156. }
  157. } else {
  158. return undefined
  159. }
  160. })
  161. return {
  162. ...formInput,
  163. selectTableProps,
  164. securityConfig,
  165. proxyOtherValue,
  166. multiple,
  167. optionProps,
  168. tableDialog,
  169. defaultValue,
  170. openDialog,
  171. onConfirm,
  172. cacheSelectItem,
  173. Search
  174. }
  175. }
  176. }
  177. </script>
  178. <style lang="less">
  179. .select-input-table-dialog{
  180. .dialog-tags{
  181. flex-basis: 220px;
  182. }
  183. }
  184. .select-input__dialog{
  185. .@{elNamespace}-dialog__body{
  186. padding: 0;
  187. }
  188. }
  189. </style>