2021-06-10 15:04:57 +00:00
|
|
|
import { defineComponent, onBeforeUnmount, onMounted, onUpdated, ref } from 'vue';
|
2020-10-17 03:23:31 +00:00
|
|
|
import moment from 'moment';
|
|
|
|
import interopDefault from '../_util/interopDefault';
|
2020-10-17 03:51:17 +00:00
|
|
|
import initDefaultProps from '../_util/props-util/initDefaultProps';
|
2020-10-17 03:23:31 +00:00
|
|
|
import Statistic, { StatisticProps } from './Statistic';
|
2021-06-10 15:04:57 +00:00
|
|
|
import { formatCountdown as formatCD, countdownValueType, FormatConfig } from './utils';
|
2020-10-17 03:23:31 +00:00
|
|
|
|
|
|
|
const REFRESH_INTERVAL = 1000 / 30;
|
2020-10-17 03:51:17 +00:00
|
|
|
|
|
|
|
function getTime(value?: countdownValueType) {
|
2020-10-17 03:23:31 +00:00
|
|
|
return interopDefault(moment)(value).valueOf();
|
|
|
|
}
|
|
|
|
|
2020-10-17 03:51:17 +00:00
|
|
|
export default defineComponent({
|
2020-10-17 03:23:31 +00:00
|
|
|
name: 'AStatisticCountdown',
|
2020-10-17 03:51:17 +00:00
|
|
|
props: initDefaultProps(StatisticProps, {
|
|
|
|
format: 'HH:mm:ss',
|
|
|
|
}),
|
2021-06-10 15:04:57 +00:00
|
|
|
emits: ['finish', 'change'],
|
|
|
|
setup(props, { emit }) {
|
|
|
|
const countdownId = ref<number>();
|
|
|
|
const statistic = ref();
|
|
|
|
const syncTimer = () => {
|
|
|
|
const { value } = props;
|
2020-10-17 03:51:17 +00:00
|
|
|
const timestamp = getTime(value);
|
2020-10-17 03:23:31 +00:00
|
|
|
if (timestamp >= Date.now()) {
|
2021-06-10 15:04:57 +00:00
|
|
|
startTimer();
|
2020-10-17 03:23:31 +00:00
|
|
|
} else {
|
2021-06-10 15:04:57 +00:00
|
|
|
stopTimer();
|
2020-10-17 03:23:31 +00:00
|
|
|
}
|
2021-06-10 15:04:57 +00:00
|
|
|
};
|
2020-10-17 03:23:31 +00:00
|
|
|
|
2021-06-10 15:04:57 +00:00
|
|
|
const startTimer = () => {
|
|
|
|
if (countdownId.value) return;
|
|
|
|
const timestamp = getTime(props.value);
|
|
|
|
countdownId.value = window.setInterval(() => {
|
|
|
|
statistic.value.$forceUpdate();
|
|
|
|
if (timestamp > Date.now()) {
|
|
|
|
emit('change', timestamp - Date.now());
|
|
|
|
}
|
2021-06-18 08:09:03 +00:00
|
|
|
syncTimer();
|
2020-10-17 03:23:31 +00:00
|
|
|
}, REFRESH_INTERVAL);
|
2021-06-10 15:04:57 +00:00
|
|
|
};
|
2020-10-17 03:23:31 +00:00
|
|
|
|
2021-06-10 15:04:57 +00:00
|
|
|
const stopTimer = () => {
|
|
|
|
const { value } = props;
|
2021-06-11 14:06:25 +00:00
|
|
|
if (countdownId.value) {
|
2021-06-10 15:04:57 +00:00
|
|
|
clearInterval(countdownId.value);
|
|
|
|
countdownId.value = undefined;
|
2020-10-17 03:23:31 +00:00
|
|
|
|
2020-10-17 03:51:17 +00:00
|
|
|
const timestamp = getTime(value);
|
2020-10-17 03:23:31 +00:00
|
|
|
if (timestamp < Date.now()) {
|
2021-06-10 15:04:57 +00:00
|
|
|
emit('finish');
|
2020-10-17 03:23:31 +00:00
|
|
|
}
|
|
|
|
}
|
2021-06-10 15:04:57 +00:00
|
|
|
};
|
2020-10-17 03:23:31 +00:00
|
|
|
|
2021-06-10 15:04:57 +00:00
|
|
|
const formatCountdown = ({
|
|
|
|
value,
|
|
|
|
config,
|
|
|
|
}: {
|
|
|
|
value: countdownValueType;
|
|
|
|
config: FormatConfig;
|
|
|
|
}) => {
|
|
|
|
const { format } = props;
|
|
|
|
return formatCD(value, { ...config, format });
|
|
|
|
};
|
2020-10-17 03:23:31 +00:00
|
|
|
|
2021-06-10 15:04:57 +00:00
|
|
|
const valueRenderHtml = (node: any) => node;
|
|
|
|
onMounted(() => {
|
|
|
|
syncTimer();
|
|
|
|
});
|
|
|
|
onUpdated(() => {
|
|
|
|
syncTimer();
|
|
|
|
});
|
|
|
|
onBeforeUnmount(() => {
|
|
|
|
stopTimer();
|
|
|
|
});
|
|
|
|
return () => {
|
|
|
|
return (
|
|
|
|
<Statistic
|
|
|
|
ref={statistic}
|
|
|
|
{...{
|
|
|
|
...props,
|
|
|
|
valueRender: valueRenderHtml,
|
|
|
|
formatter: formatCountdown,
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
);
|
|
|
|
};
|
2020-10-17 03:23:31 +00:00
|
|
|
},
|
|
|
|
});
|