DateTimePick.vue 5.52 KB
Newer Older
hucy's avatar
hucy committed
1 2 3
<script lang="ts" setup>
import { onMounted, ref, reactive, computed } from 'vue';
import { date } from 'quasar';
hucy's avatar
hucy committed
4
import { isEmpty } from 'src/common/utils';
hucy's avatar
hucy committed
5 6

interface Props {
hucy's avatar
hucy committed
7
  modelValue: string | null;
hucy's avatar
hucy committed
8
  format24h?: boolean;
hucy's avatar
hucy committed
9
  dense?: boolean;
hucy's avatar
hucy committed
10 11
  disable?: boolean;
  readonly?: boolean;
hucy's avatar
hucy committed
12
  config?: any;
hucy's avatar
hucy committed
13 14
}
const props = withDefaults(defineProps<Props>(), {
hucy's avatar
hucy committed
15 16
  // modelValue: date.formatDate(Date.now(), 'YYYY/MM/DD HH:mm'),
  modelValue: null,
hucy's avatar
hucy committed
17
  format24h: false,
hucy's avatar
hucy committed
18
  dense: false,
hucy's avatar
hucy committed
19 20
  disable: false,
  readonly: false,
hucy's avatar
hucy committed
21 22 23
  config: () => {
    return {};
  },
hucy's avatar
hucy committed
24 25 26 27 28 29 30
});

const emit = defineEmits<{
  (e: 'update:modelValue', value: string): void;
}>();

const dates = computed({
hucy's avatar
hucy committed
31
  set(value: any) {
hucy's avatar
hucy committed
32 33 34
    emit('update:modelValue', value);
  },
  get() {
hucy's avatar
hucy committed
35
    // console.log('get', props.modelValue);
hucy's avatar
hucy committed
36 37 38 39
    return props.modelValue;
  },
});

hucy's avatar
hucy committed
40 41 42 43 44 45 46 47 48
const dateMask = computed(() => {
  let obj = {
    date: 'YYYY/MM/DD',
    time: 'HH:mm:ss',
  };
  if (!isEmpty(props.config) && props.config.dateMask) {
    const maskList = props.config.dateMask.split(' ');
    obj.date = maskList[0];
    obj.time = maskList[1] || '';
hucy's avatar
hucy committed
49
  }
hucy's avatar
hucy committed
50
  return obj;
hucy's avatar
hucy committed
51 52
});

hucy's avatar
hucy committed
53 54
const isWithSeconds = computed(() => {
  return dateMask.value.time.length > 6;
hucy's avatar
hucy committed
55 56
});

hucy's avatar
hucy committed
57 58 59 60 61 62 63 64 65 66 67 68 69
// const dateRules = computed(() => {
//   let dateRegular: RegExp;
//   if (props.withSeconds) {
//     dateRegular =
//       /^-?[\d]+\/[0-1]\d\/[0-3]\d ([0-1]?\d|2[0-3]):[0-5]\d:[0-5]\d$/;
//   } else {
//     dateRegular = /^-?[\d]+\/[0-1]\d\/[0-3]\d (\d{2}):(\d{2})$/;
//   }
//   return [(v: string) => dateRegular.test(v)];
// });

const dateProxyDate = ref<any>(null);
const timeProxyDate = ref<any>(null);
hucy's avatar
hucy committed
70 71 72 73 74 75 76 77 78 79 80 81 82
const dateLocale = reactive({
  daysShort: '六_日_一_二_三_四_五'.split('_'),
  months:
    '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split(
      '_'
    ),
  monthsShort: '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),
  firstDayOfWeek: 1,
  format24h: true,
  pluralDay: 'dias',
});

onMounted(() => {
hucy's avatar
hucy committed
83
  // console.log('999', props.config);
hucy's avatar
hucy committed
84

hucy's avatar
hucy committed
85 86 87 88
  getNowDate();
});

function getNowDate() {
hucy's avatar
hucy committed
89 90
  dateProxyDate.value = date.formatDate(Date.now(), dateMask.value.date);
  timeProxyDate.value = date.formatDate(Date.now(), dateMask.value.time);
hucy's avatar
hucy committed
91 92 93 94
}

function updateProxy() {
  const _dates = dates.value;
hucy's avatar
hucy committed
95 96
  if (_dates) {
    const dateArr = _dates.split(' ');
hucy's avatar
hucy committed
97

hucy's avatar
hucy committed
98 99 100 101 102 103
    dateProxyDate.value = dateArr[0];
    timeProxyDate.value = dateArr[1];
  } else {
    dateProxyDate.value = null;
    timeProxyDate.value = null;
  }
hucy's avatar
hucy committed
104 105 106
}

function onClickDate() {
hucy's avatar
hucy committed
107 108 109 110
  let datesStr = dateProxyDate.value;
  if (timeProxyDate.value) {
    datesStr = `${dateProxyDate.value} ${timeProxyDate.value}`;
  }
hucy's avatar
hucy committed
111 112 113 114 115
  dates.value = datesStr;
}
</script>
<template>
  <div class="hcy-datetime-pick">
hucy's avatar
hucy committed
116 117 118 119 120 121 122 123 124
    <q-input
      v-model="dates"
      v-bind="config"
      :dense="config.dense === undefined ? props.dense : config.dense"
      :disable="config.disable === undefined ? props.disable : config.disable"
      :readonly="
        config.readonly === undefined ? props.readonly : config.readonly
      "
    >
hucy's avatar
hucy committed
125 126 127
      <template v-slot:append>
        <q-icon name="event" class="cursor-pointer">
          <q-popup-proxy
hucy's avatar
hucy committed
128
            v-if="!props.readonly"
hucy's avatar
hucy committed
129 130 131 132 133 134 135 136 137 138 139
            @before-show="updateProxy"
            transition-show="scale"
            transition-hide="scale"
            class="row"
          >
            <q-date
              flat
              square
              minimal
              v-model="dateProxyDate"
              :locale="dateLocale"
hucy's avatar
hucy committed
140
              :mask="dateMask.date"
hucy's avatar
hucy committed
141 142
              class="my-date"
            >
hucy's avatar
hucy committed
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
              <div
                class="row items-center justify-end q-gutter-sm"
                v-if="!dateMask.time"
              >
                <q-btn
                  label="此刻"
                  size="sm"
                  color="primary"
                  flat
                  @click="getNowDate"
                />
                <q-btn
                  unelevated
                  label="确定"
                  size="sm"
                  color="primary"
                  @click="onClickDate"
                  v-close-popup
                />
              </div>
hucy's avatar
hucy committed
163 164
            </q-date>
            <q-time
hucy's avatar
hucy committed
165
              v-if="dateMask.time"
hucy's avatar
hucy committed
166 167 168
              flat
              square
              v-model="timeProxyDate"
hucy's avatar
hucy committed
169
              :mask="dateMask.time"
hucy's avatar
hucy committed
170
              :format24h="format24h"
hucy's avatar
hucy committed
171
              :with-seconds="isWithSeconds"
hucy's avatar
hucy committed
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221
              text-color="primary"
              class="my-time"
            >
              <div class="row items-center justify-end q-gutter-sm">
                <q-btn
                  label="此刻"
                  size="sm"
                  color="primary"
                  flat
                  @click="getNowDate"
                />
                <q-btn
                  unelevated
                  label="确定"
                  size="sm"
                  color="primary"
                  @click="onClickDate"
                  v-close-popup
                />
              </div>
            </q-time>
          </q-popup-proxy>
        </q-icon>
      </template>
    </q-input>
  </div>
</template>

<style lang="scss" scoped>
.my-date {
  :deep(.q-date__main .q-date__content .q-date__view .q-date__navigation) {
    > .relative-position {
      color: $primary;
    }
  }
}
.my-time {
  :deep(.q-time__header) {
    background-color: white;
  }
  :deep(.q-time__main
      .q-time__content
      .q-time__container-child
      .q-time__clock
      .q-time__clock-circle
      .q-time__clock-position--active) {
    color: white !important;
  }
}
</style>