327 lines
10 KiB
Vue
Raw Normal View History

2025-05-22 16:23:08 +08:00
<template>
<page-meta>
<navigation-bar :title="$tt('navBar.timer')" title-align="center" background-color="#F1F3F9"
front-color="#000000">
</navigation-bar>
</page-meta>
<view class="scene-timing-wrap">
<view class="container-wrap">
<view class="form-wrap">
<u--form :model="form" ref="form" :rules="rules" errorType="toast" labelPosition="left" labelWidth="80">
<view class="form-item-wrap">
<u-form-item prop="time" :label="$tt('sceneTiming.time')"
@click="form.isAdvance !== 1 && (isTimer = true)">
<u--input v-model="form.time" border="none" inputAlign="right"
:placeholder="$tt('sceneTiming.selectTime')" disabledColor="#fff" disabled
:customStyle="{ marginRight: '20rpx', pointerEvents: 'none' }" />
<u-icon slot="right" name="arrow-right"></u-icon>
</u-form-item>
</view>
<view class="form-item-wrap">
<u-form-item prop="repeat" :label="$tt('sceneTiming.again')" :disabled="form.isAdvance==1"
@click="form.isAdvance !== 1 && (isRepeat = true)">
<u--input v-model="form.repeat" border="none" inputAlign="right"
:placeholder="$tt('sceneTiming.selectWeek')" disabledColor="#fff" disabled
:customStyle="{ marginRight: '20rpx', pointerEvents: 'none' }" />
<u-icon slot="right" name="arrow-right"></u-icon>
</u-form-item>
</view>
<view class="form-item-wrap">
<u-form-item label="CRON">
<template slot="right">
<u-radio-group v-model="form.isAdvance">
<u-radio :customStyle="{marginRight: '30rpx'}" :label="$tt('sceneTiming.default')"
:name="0"></u-radio>
<u-radio :customStyle="{marginRight: '10rpx'}" :label="$tt('sceneTiming.auto')"
:name="1"></u-radio>
</u-radio-group>
</template>
</u-form-item>
</view>
<view class="form-item-wrap">
<u-form-item>
<!-- #ifndef APP-NVUE -->
<u-input v-model="form.cronExpression" :placeholder="$tt('sceneTiming.inputCRON')" disabled>
<!-- #endif -->
<!-- #ifdef APP-NVUE -->
<u--input v-model="form.cronExpression" :placeholder="$tt('sceneTiming.inputCRON')"
disabled>
<!-- #endif -->
<template slot="suffix">
<u-button :text="$tt('sceneTiming.expression')" icon="calendar" type="primary"
size="mini" :disabled="form.isAdvance==0" @click="genExpression"></u-button>
</template>
<!-- #ifndef APP-NVUE -->
</u-input>
<!-- #endif -->
<!-- #ifdef APP-NVUE -->
</u--input>
<!-- #endif -->
</u-form-item>
</view>
</u--form>
</view>
<view class="btn-wrap">
<u-button :customStyle="{ height: '96rpx', color: '#3378FE', borderRadius: '10px' }" size="normal"
:plain="true" :text="$tt('common.save')" @click="handleSave"></u-button>
</view>
</view>
<view class="other">
<!-- 选择时间 -->
<u-datetime-picker :show="isTimer" v-model="form.time" mode="time" @cancel="isTimer=false"
@close="isTimer=false" @confirm="handleDatetimeConfirm"></u-datetime-picker>
<!-- 星期 -->
<u-popup :show="isRepeat" :round="5" mode="bottom" bgColor="#eef3f7" :closeOnClickOverlay="true"
@close="isRepeat = false">
<view class="repeat-popup-wrap">
<view class="nav">
<text @click="isRepeat = false">{{$tt('common.cancel')}}</text>
<text @click="handleRepeatConfirm">{{$tt('common.confirm')}}</text>
</view>
<view class="radio-group-wrap">
<u-checkbox-group v-model="repeatValue" :borderBottom="false" placement="column"
iconPlacement="right">
<view class="radio-wrap">
<u-checkbox :label="$tt('sceneTiming.monday')" :name="1" iconSize="16"></u-checkbox>
</view>
<view class="radio-wrap">
<u-checkbox :label="$tt('sceneTiming.tuesday')" :name="2" iconSize="16"></u-checkbox>
</view>
<view class="radio-wrap">
<u-checkbox :label="$tt('sceneTiming.wednesday')" :name="3" iconSize="16"></u-checkbox>
</view>
<view class="radio-wrap">
<u-checkbox :label="$tt('sceneTiming.thursday')" :name="4" iconSize="16"></u-checkbox>
</view>
<view class="radio-wrap">
<u-checkbox :label="$tt('sceneTiming.friday')" :name="5" iconSize="16"></u-checkbox>
</view>
<view class="radio-wrap">
<u-checkbox :label="$tt('sceneTiming.saturday')" :name="6" iconSize="16"></u-checkbox>
</view>
<view class="radio-wrap">
<u-checkbox :label="$tt('sceneTiming.sunday')" :name="7" iconSize="16"></u-checkbox>
</view>
</u-checkbox-group>
</view>
</view>
</u-popup>
</view>
</view>
</template>
<script>
import { navigateBackTo } from '@/utils/common.js';
export default {
data() {
return {
type: 'trigger',
editIndex: null, // null 代表新增
isTimer: false, // 时间
isRepeat: false, // 星期
form: {
time: uni.$u.timeFormat(new Date(), 'hh:MM'),
repeat: this.$tt('sceneTiming.everyDay'),
isAdvance: 0,
cronExpression: `0 ${uni.$u.timeFormat(new Date(),'MM')} ${uni.$u.timeFormat(new Date(),'hh')} ? * 1,2,3,4,5,6,7`,
},
rules: {
time: {
type: 'string',
required: true,
message: this.$tt('sceneTiming.selectTime'),
trigger: ['blur', 'change']
},
repeat: {
type: 'string',
required: true,
message: this.$tt('sceneTiming.selectWeek'),
trigger: ['blur', 'change']
},
},
repeatValue: [1, 2, 3, 4, 5, 6, 7],
};
},
onLoad(options) {
const { type, editIndex, crontabValueString } = options;
this.type = type;
this.editIndex = Number(editIndex);
if (crontabValueString) {
this.form.isAdvance = 1;
this.form.cronExpression = crontabValueString;
} else {
if (!Number.isNaN(this.editIndex) && this.editIndex !== null) {
const { cronExpression } = uni.getStorageSync('trigger');
const time = cronExpression.substring(5, 7) + ':' + cronExpression.substring(2, 4);
const repeatValue = cronExpression.substring(12).split(',').map(Number);
const repeat = this.getRepeatName(repeatValue)
this.form = { ...this.form, time, repeat, cronExpression };
this.repeatValue = repeatValue;
}
}
},
methods: {
// 时间选择
handleDatetimeConfirm() {
this.$nextTick(() => {
this.gentCronExpression();
})
this.isTimer = false;
},
// 星期选择
handleRepeatConfirm() {
const repeat = this.getRepeatName(this.repeatValue);
this.form.repeat = repeat;
this.gentCronExpression();
this.isRepeat = false;
},
// 获取repeat名称
getRepeatName(repeatValue) {
const list = repeatValue.map(item => {
if (item === 1) {
return this.$tt('sceneTiming.monday')
} else if (item === 2) {
return this.$tt('sceneTiming.tuesday')
} else if (item === 3) {
return this.$tt('sceneTiming.wednesday')
} else if (item === 4) {
return this.$tt('sceneTiming.thursday')
} else if (item === 5) {
return this.$tt('sceneTiming.friday')
} else if (item === 6) {
return this.$tt('sceneTiming.saturday')
} else if (item === 7) {
return this.$tt('sceneTiming.sunday')
}
})
if (list.length === 7) {
return this.$tt('sceneTiming.everyDay');
} else {
return list.join(',');
}
},
// 生成cron表达式
gentCronExpression() {
let hour = '00';
let minute = '00';
if (this.form.time) {
hour = this.form.time.substring(0, 2);
minute = this.form.time.substring(3);
}
let week = '*';
if (this.repeatValue.length > 0) {
week = this.repeatValue.sort();
week = week.map(weekNumber => {
return (weekNumber % 7) + 1;
});
}
this.form.cronExpression = '0 ' + minute + ' ' + hour + ' ? * ' + week;
},
//自定义生成表达式
genExpression() {
uni.setStorageSync('type', this.type);
uni.setStorageSync('editIndex', this.editIndex);
uni.$u.route('/pagesA/scene/timing/express');
},
// 保存
handleSave() {
this.$refs.form.validate().then(respon => {
let action = uni.getStorageSync(this.type);
const { cronExpression } = this.form;
action = { ...action, cronExpression };
uni.setStorageSync(this.type, action);
// 更新或者插入新的触发或者执行
let { triggers, actions, ...res } = uni.getStorageSync('sceneData');
if (Number.isNaN(this.editIndex) || this.editIndex === null) {
if (this.type === 'trigger') {
triggers.push(action);
} else {
actions.push(action);
}
uni.setStorageSync('sceneData', { triggers, actions, ...res });
} else {
if (this.type === 'trigger') {
let list = triggers.map((item, i) => {
if (i == this.editIndex) {
return action
} else {
return item
}
});
uni.setStorageSync('sceneData', { triggers: [...list], actions, ...res });
} else {
let list = actions.map((item, i) => {
if (i == this.editIndex) {
return action
} else {
return item
}
});
uni.setStorageSync('sceneData', { triggers, actions: [...list], ...res });
}
}
uni.setStorageSync('callback', true);
navigateBackTo('/pagesA/scene/detail');
})
}
}
};
</script>
<style lang="scss">
page {
height: 100%;
background: $uni-bg-color-grey;
}
</style>
<style lang="scss" scoped>
.scene-timing-wrap {
.container-wrap {
.form-wrap {
background: #fff;
margin: 30rpx;
border-radius: 10rpx;
.form-item-wrap {
padding: 4rpx 20rpx;
}
}
.btn-wrap {
margin: 30rpx 26rpx;
}
}
.other {
.repeat-popup-wrap {
padding: 30rpx;
.nav {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
font-size: 32rpx;
margin-bottom: 34rpx;
}
.radio-group-wrap {
background-color: #fff;
border-radius: 10rpx;
.radio-wrap {
padding: 32rpx;
&:not(:last-child) {
border-bottom: 1rpx solid #F1F2F5;
}
}
}
}
}
}
</style>