index.vue 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. <template>
  2. <el-date-picker
  3. :class="['cip-form-picker',{ 'cip-form-picker--no-icon': noIcon }, $attrs.class]"
  4. v-model="proxyValue"
  5. :format="formatter"
  6. :disabled="disabled"
  7. :type="type"
  8. :placeholder="placeholder"
  9. :clearable="clearable"
  10. :style="{width}"
  11. :onBlur="(e)=>$emit('blur',e)"
  12. :onFocus="(e)=>$emit('focus',e)"
  13. :disabled-date="disabledDate"
  14. />
  15. </template>
  16. <script>
  17. import { ElDatePicker } from 'element-plus'
  18. import { useFormInput } from '@cip/components/hooks/form-input'
  19. import { formInputProps, fromInputEmits } from '../../form-input-props'
  20. import { computed } from 'vue'
  21. import dayjs from 'dayjs'
  22. import advancedFormat from 'dayjs/plugin/advancedFormat'
  23. import weekYear from 'dayjs/plugin/weekYear'
  24. import weekOfYear from 'dayjs/plugin/weekOfYear'
  25. import { isArray, isNotEmpty, isNumber } from '@cip/utils/util'
  26. dayjs.extend(advancedFormat)
  27. dayjs.extend(weekYear)
  28. dayjs.extend(weekOfYear)
  29. export default {
  30. components: { ElDatePicker },
  31. props: formInputProps,
  32. inheritAttrs: false,
  33. emits: [...fromInputEmits, 'focus', 'blur'],
  34. setup (props, context) {
  35. // 不同事件类型传值不同,做转换
  36. const disabled = computed(() => {
  37. return securityConfig.value.disabled ?? false
  38. })
  39. const noIcon = computed(() => {
  40. return securityConfig.value.noIcon
  41. })
  42. const isTimestamp = computed(() => {
  43. return securityConfig.value.isTimestamp ?? false
  44. })
  45. const formatter = computed(() => {
  46. if (securityConfig.value.formatter) return securityConfig.value.formatter
  47. const typeToFormatter = {
  48. year: 'YYYY',
  49. month: 'YYYY-MM',
  50. week: 'YYYY 第 ww 周',
  51. date: 'YYYY-MM-DD',
  52. datetime: 'YYYY-MM-DD HH:mm:ss'
  53. }
  54. return typeToFormatter[type.value] ?? typeToFormatter.date
  55. })
  56. const typeToValueMap = {
  57. dates: (val) => {
  58. if (!isArray(val)) val = [val]
  59. return val?.map(i => dayjs(i).format(formatter.value)).join(',')
  60. },
  61. datetime: val => dayjs(val).format('YYYY-MM-DD HH:mm:ss'),
  62. week: val => dayjs(val).format('YYYY-MM-DD')
  63. }
  64. const typeToValue = (val) => {
  65. if (!val) return ''
  66. if (isTimestamp.value) return new Date(val).getTime()
  67. if (securityConfig.value.isOtherDate) {
  68. // viewType为date时,返回值修改时分秒为23:59:59
  69. const modelValue = new Date(val).getTime() + 86400000 - 1000
  70. return dayjs(modelValue).format(formatter.value)
  71. }
  72. return typeToValueMap?.[type.value]?.(val) ?? dayjs(val).format(formatter.value)
  73. }
  74. const getValue = () => {
  75. if (!props.modelValue) return null
  76. // week的modelValue值应为选择的某一天,formatter为第几周
  77. if (type.value === 'week') return dayjs(props.modelValue).format('YYYY-MM-DD')
  78. // 时间戳modelValue转成formatter格式,向外抛出时重置为时间戳格式
  79. if (isTimestamp.value) return dayjs(props.modelValue).format(formatter.value)
  80. // dates时modelValue是个数组
  81. if (type.value === 'dates') return props.modelValue.split(',')
  82. return dayjs(props.modelValue).format(formatter.value)
  83. }
  84. const { securityConfig, ...formInput } = useFormInput(props, context, {
  85. fromModelValue: getValue,
  86. toModelValue: typeToValue
  87. })
  88. const type = computed(() => {
  89. const viewType = securityConfig.value.viewType ?? 'date'
  90. return viewType.includes('range') ? 'date' : viewType
  91. })
  92. // 是否包含等于
  93. const isEqual = computed(() => {
  94. return securityConfig.value.isEqual ?? false
  95. })
  96. // disable日期
  97. const disabledDate = computed(() => {
  98. return date => {
  99. if (securityConfig.value.disabledDate) {
  100. return securityConfig.value.disabledDate(date)
  101. }
  102. if (isNotEmpty(securityConfig.value.max) || isNotEmpty(securityConfig.value.min)) {
  103. return getDisabledConfig(date)
  104. }
  105. return undefined
  106. }
  107. })
  108. // disable时间转换
  109. const dateTransform = (date) => {
  110. if (isNumber(date)) return date
  111. if (!date?.includes(' ')) return new Date(date + ' 00:00:00').getTime()
  112. return new Date(date).getTime()
  113. }
  114. // min/max的disable实现
  115. const getDisabledConfig = (date) => {
  116. const maxDate = dateTransform(securityConfig.value.max)
  117. const minDate = dateTransform(securityConfig.value.min)
  118. const dateTime = date.getTime()
  119. if (isNotEmpty(securityConfig.value.max) && isNotEmpty(securityConfig.value.min)) {
  120. if (isEqual.value) return (dateTime >= maxDate) || (dateTime <= minDate)
  121. return (dateTime > maxDate) || (dateTime < minDate)
  122. }
  123. if (isNotEmpty(securityConfig.value.max)) {
  124. if (isEqual.value) return dateTime >= maxDate
  125. return dateTime > maxDate
  126. }
  127. if (isNotEmpty(securityConfig.value.min)) {
  128. if (isEqual.value) return dateTime <= minDate
  129. return dateTime < minDate
  130. }
  131. }
  132. return {
  133. ...formInput,
  134. disabled,
  135. formatter,
  136. type,
  137. noIcon,
  138. disabledDate
  139. }
  140. }
  141. }
  142. </script>
  143. <style lang="less">
  144. .@{elNamespace}-input.@{elNamespace}-date-editor.cip-form-picker{
  145. width: 100%;
  146. &--no-icon{
  147. .@{elNamespace}-input__prefix{
  148. display: none;
  149. }
  150. }
  151. }
  152. </style>