| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519 |
- <template>
- <div
- class="c-grid-form medium c-event"
- :class="{ row: !vertical, col: vertical }"
- >
- <div class="c-grid-form__label required">播放内容</div>
- <div class="c-event__option c-event__program u-pointer">
- <div
- class="c-event__name has-padding--h"
- @click="onChoose"
- >
- <div class="u-ellipsis">{{ msg }}</div>
- </div>
- </div>
- <div class="c-grid-form__label">播放方式</div>
- <div>
- <el-select
- v-model="eventOptions.freq"
- class="c-event__option"
- @change="onEventTypeChanged"
- >
- <el-option
- v-for="option in freqOptions"
- :key="option.value"
- :label="option.label"
- :value="option.value"
- />
- </el-select>
- </div>
- <template v-if="isOnce">
- <div class="c-grid-form__label required">生效时间</div>
- <el-date-picker
- v-model="eventOptions.start"
- class="c-event__option"
- type="datetime"
- placeholder="请选择生效时间"
- value-format="yyyy-MM-dd HH:mm:ss"
- :picker-options="pickerOptions"
- @change="onDateTimeChange('start')"
- />
- <div class="c-grid-form__label required">失效时间</div>
- <el-date-picker
- v-model="eventOptions.until"
- class="c-event__option"
- type="datetime"
- :disabled="!eventOptions.start"
- placeholder="请选择失效时间"
- value-format="yyyy-MM-dd HH:mm:ss"
- :picker-options="endPickerOptions"
- @change="onDateTimeChange('until')"
- />
- </template>
- <template v-if="isWeekly">
- <div class="c-grid-form__label c-grid-form__auto required">每周</div>
- <el-checkbox-group
- v-model="eventOptions.byDay"
- class="c-grid-form__auto l-flex--row c-event__option"
- size="mini"
- fill="#1c5cb0"
- >
- <el-checkbox-button
- v-for="week in weeks"
- :key="week.value"
- :label="week.value"
- >
- {{ week.label }}
- </el-checkbox-button>
- </el-checkbox-group>
- <div class="c-grid-form__label required">开始时间</div>
- <el-time-picker
- v-model="eventOptions.startTime"
- class="c-event__option"
- placeholder="请选择开始时间"
- value-format="HH:mm:ss"
- :clearable="false"
- />
- <div class="c-grid-form__label required">结束时间</div>
- <el-time-picker
- v-model="eventOptions.endTime"
- class="c-grid-form__info c-event__option"
- data-info="结束时间小于等于开始时间为跨天播放"
- placeholder="请选择结束时间"
- value-format="HH:mm:ss"
- :clearable="false"
- />
- <div class="c-grid-form__label required">生效日期</div>
- <el-date-picker
- v-model="eventOptions.start"
- class="c-event__option"
- type="date"
- placeholder="请选择生效日期"
- value-format="yyyy-MM-dd HH:mm:ss"
- :picker-options="pickerOptions"
- @change="onDateTimeChange('start')"
- />
- <div class="c-grid-form__label required">失效日期</div>
- <el-date-picker
- v-model="eventOptions.until"
- class="c-grid-form__info c-event__option"
- data-info="失效日期当天不触发"
- type="date"
- :disabled="!eventOptions.start"
- placeholder="请选择失效日期"
- value-format="yyyy-MM-dd HH:mm:ss"
- :picker-options="endPickerOptions"
- @change="onDateTimeChange('until')"
- />
- </template>
- <template v-if="isCount">
- <div class="c-grid-form__label">次数</div>
- <el-input-number
- v-model="eventOptions.count"
- :min="1"
- :max="99999999"
- :step="1"
- step-strictly
- />
- <div class="c-grid-form__label required">开始时间</div>
- <el-date-picker
- v-model="eventOptions.start"
- class="c-event__option"
- type="datetime"
- placeholder="请选择生效时间"
- value-format="yyyy-MM-dd HH:mm:ss"
- :picker-options="pickerOptions"
- />
- <template v-if="untilDate">
- <div class="c-grid-form__label">结束时间</div>
- <el-date-picker
- :value="untilDate"
- class="c-event__option"
- type="datetime"
- disabled
- />
- </template>
- </template>
- <event-target-dialog
- ref="eventTargetDialog"
- v-bind="$attrs"
- @choosen="onChoosen"
- />
- </div>
- </template>
- <script>
- import {
- EventPriority,
- EventFreq,
- EventTarget
- } from '@/constant'
- import { getSchedule } from '@/api/calendar'
- import { getProgram } from '@/api/program'
- import {
- isMoreThanOneWeek,
- getNearestHitDate,
- isOverDay
- } from '@/utils/event'
- import { parseTime } from '@/utils'
- const EventFreqCount = 'COUNT'
- export default {
- name: 'EventPicker',
- props: {
- event: {
- type: Object,
- default: null
- },
- priority: {
- type: Number,
- default: EventPriority.NORMAL
- },
- vertical: {
- type: [Boolean, String],
- default: false
- }
- },
- data () {
- return {
- freqOptions: [
- { value: EventFreq.ONCE, label: '时段播放' },
- { value: EventFreq.WEEKLY, label: '重复播放' },
- { value: EventFreqCount, label: '按次播放' }
- ],
- weeks: [
- { value: '0', label: '日' },
- { value: '1', label: '一' },
- { value: '2', label: '二' },
- { value: '3', label: '三' },
- { value: '4', label: '四' },
- { value: '5', label: '五' },
- { value: '6', label: '六' }
- ],
- eventOptions: null,
- eventTarget: null
- }
- },
- computed: {
- isOnce () {
- return this.eventOptions.freq === EventFreq.ONCE
- },
- isWeekly () {
- return this.eventOptions.freq === EventFreq.WEEKLY
- },
- isCount () {
- return this.eventOptions.freq === EventFreqCount
- },
- pickerOptions () {
- return {
- disabledDate: this.isDisableDate
- }
- },
- endPickerOptions () {
- return {
- disabledDate: this.isDisableEndDate
- }
- },
- minDate () {
- const now = new Date()
- return new Date(now.getFullYear(), now.getMonth(), now.getDate())
- },
- msg () {
- return this.eventTarget ? this.eventTarget.name : '点击选择播放内容'
- },
- untilDate () {
- if (this.isCount && this.eventTarget) {
- const { start, count } = this.eventOptions
- const { duration } = this.eventTarget
- if (start && duration) {
- return new Date(start).getTime() + duration * count * 1000
- }
- }
- return null
- }
- },
- watch: {
- event: {
- handler () {
- this.init()
- },
- immediate: true
- }
- },
- methods: {
- isDisableDate (date) {
- return date < this.minDate
- },
- isDisableEndDate (date) {
- if (date < this.minDate) {
- return true
- }
- if (this.eventOptions.start) {
- if (this.isWeekly) {
- return date <= new Date(this.eventOptions.start)
- }
- return date < new Date(this.eventOptions.start)
- }
- return false
- },
- init () {
- const { freq, byDay, target, ...options } = {
- freq: EventFreq.ONCE,
- start: null,
- until: null,
- startTime: '00:00:00',
- endTime: '00:00:00',
- ...this.event
- }
- if (freq === EventFreq.ONCE && target?.duration) {
- const { start, until } = options
- this.eventOptions = {
- ...options,
- freq: EventFreqCount,
- count: (new Date(until) - new Date(start)) / target.duration / 1000,
- byDay: byDay ? byDay.split(',') : []
- }
- } else {
- this.eventOptions = {
- ...options,
- freq,
- count: 1,
- byDay: byDay ? byDay.split(',') : []
- }
- }
- this.eventTarget = target
- },
- onDateTimeChange (type) {
- const { start, until } = this.eventOptions
- if (start && until && start > until) {
- if (type === 'start') {
- this.eventOptions.until = start
- } else {
- this.eventOptions.start = until
- }
- }
- },
- onChoose () {
- this.$refs.eventTargetDialog.show()
- },
- onChoosen ({ value, done }) {
- done()
- this.eventTarget = value
- this.onCheckCount()
- this.$emit('choosen', value)
- },
- onEventTypeChanged () {
- this.onCheckCount()
- if (this.isCount) {
- this.eventOptions.until = null
- }
- },
- onCheckCount () {
- if (this.eventTarget && this.isCount) {
- this.getDuration(this.eventTarget).then(
- duration => {
- this.eventTarget = {
- ...this.eventTarget,
- duration
- }
- },
- ({ isCancel }) => {
- if (!isCancel) {
- this.$message({
- type: 'wanring',
- message: '暂无节目时长,将使用默认值(1分钟)'
- })
- this.eventTarget = {
- ...this.eventTarget,
- duration: 60
- }
- }
- }
- )
- }
- },
- getDuration ({ duration, type, id }) {
- if (duration === 0) {
- return Promise.reject()
- }
- if (!duration) {
- const loading = this.$showLoading()
- switch (type) {
- case EventTarget.RECUR:
- return getSchedule(id)
- .then(({ events }) => events.reduce((total, { spend }) => total + spend, 0))
- .finally(() => {
- this.$closeLoading(loading)
- })
- default:
- return getProgram(id)
- .then(({ data }) => Number(data.duration))
- .finally(() => {
- this.$closeLoading(loading)
- })
- }
- }
- return Promise.resolve(duration)
- },
- isEventTargetMatchEventFreq () {
- if (this.eventTarget && this.isCount) {
- return this.eventTarget.type === ''
- }
- return true
- },
- onError (message) {
- this.$message({
- type: 'warning',
- message
- })
- return null
- },
- isOnceSame () {
- const { freq, byDay, startTime, endTime } = this.eventOptions
- return freq === EventFreq.WEEKLY && byDay.length === 7 && startTime === '00:00:00' && endTime === '00:00:00'
- },
- createOnceEvent () {
- const { start, until } = this.eventOptions
- return {
- priority: this.priority,
- freq: EventFreq.ONCE,
- start, until
- }
- },
- createWeeklyEvent () {
- const { start, until, byDay, startTime, endTime } = this.eventOptions
- const byDayValue = byDay.join(',')
- const isOver = isOverDay({ startTime, endTime })
- const startWeek = new Date(start).getDay()
- const startDate = start.replace(/\d{2}:\d{2}:\d{2}$/, byDayValue.includes(startWeek) || isOver && byDayValue.includes((startWeek + 6) % 7) ? startTime : '00:00:00')
- const untilDate = until && until.replace(/\d{2}:\d{2}:\d{2}$/, isOver && byDayValue.includes((new Date(until).getDay() + 6) % 7) ? endTime : '00:00:00')
- const event = {
- priority: this.priority,
- freq: EventFreq.WEEKLY,
- start: startDate,
- until: untilDate,
- byDay: byDayValue,
- startTime,
- endTime
- }
- if (untilDate && !isMoreThanOneWeek(new Date(untilDate) - new Date(startDate)) && !getNearestHitDate(event, startDate, untilDate)) {
- return this.onError('有效日期内无法触发')
- }
- return event
- },
- createCountEvent () {
- const { start, count } = this.eventOptions
- const { duration } = this.eventTarget
- return {
- priority: this.priority,
- freq: EventFreq.ONCE,
- start,
- until: parseTime(new Date(start).getTime() + duration * count * 1000, '{y}-{m}-{d} {h}:{i}:{s}')
- }
- },
- createEventTarget () {
- const { duration, ...eventTarget } = this.eventTarget
- if (this.isCount) {
- return { ...eventTarget, duration }
- }
- return { ...eventTarget }
- },
- createEvent () {
- if (this.isWeekly && !this.isOnceSame()) {
- return this.createWeeklyEvent()
- }
- if (this.isCount) {
- return this.createCountEvent()
- }
- return this.createOnceEvent()
- },
- getValue () {
- if (!this.eventTarget) {
- return this.onError('请选择播放内容')
- }
- const { start, until } = this.eventOptions
- if (this.isOnce) {
- if (!start) {
- return this.onError('请选择生效时间')
- }
- if (!until) {
- return this.onError('请选择失效时间')
- }
- if (start === until) {
- return this.onError('生效时间与失效时间不能一样')
- }
- }
- if (this.isWeekly) {
- const { byDay, startTime, endTime } = this.eventOptions
- if (!byDay.length) {
- return this.onError('请选择生效星期')
- }
- if (!startTime) {
- return this.onError('请选择开始时间')
- }
- if (!endTime) {
- return this.onError('请选择结束时间')
- }
- if (!start) {
- return this.onError('请选择生效日期')
- }
- if (!until) {
- return this.onError('请选择失效日期')
- }
- if (start.split(' ')[0] === until.split(' ')[0]) {
- return this.onError('生效日期与失效日期不能一样')
- }
- }
- if (until && new Date(until).getTime() <= Date.now()) {
- return this.onError('结束时间小于当前时间,请配置有效的生效时间')
- }
- if (this.isCount) {
- if (!start) {
- return this.onError('请选择生效时间')
- }
- if (new Date(this.untilDate).getTime() <= Date.now()) {
- return this.onError('结束时间小于当前时间,请配置有效的生效时间或次数')
- }
- }
- return {
- ...this.createEvent(),
- target: this.createEventTarget()
- }
- }
- }
- }
- </script>
- <style lang="scss" scoped>
- .c-event {
- &.row &__option {
- width: 100%;
- }
- &__program {
- position: relative;
- height: 40px;
- color: $blue;
- font-size: 14px;
- line-height: 1;
- border-radius: $radius--mini;
- border: 1px solid #dcdfe6;
- &:hover {
- border-color: #c0c4cc;
- }
- }
- &__name {
- display: inline-flex;
- justify-content: center;
- align-items: center;
- position: absolute;
- width: 100%;
- height: 100%;
- }
- }
- </style>
|