Files
Message-Push-Nest/web/src/components/pages/cronMessages/CronMessageForm.vue
T

168 lines
5.0 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup lang="ts">
import { ref, reactive, watch } from 'vue'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'
import { Textarea } from '@/components/ui/textarea'
import { request } from '@/api/api'
interface CronMessageFormData {
id?: number
name: string
cron_expression: string
title: string
content: string
task_id: string
url: string
}
interface Props {
modelValue: CronMessageFormData
mode: 'add' | 'edit'
loading?: boolean
}
interface Emits {
(e: 'update:modelValue', value: CronMessageFormData): void
(e: 'submit'): void
(e: 'cancel'): void
}
const props = withDefaults(defineProps<Props>(), {
loading: false
})
const emit = defineEmits<Emits>()
defineOptions({
name: 'CronMessageForm'
})
// 本地表单数据
const localFormData = reactive<CronMessageFormData>({ ...props.modelValue })
// 监听外部数据变化
watch(() => props.modelValue, (newValue) => {
Object.assign(localFormData, newValue)
}, { deep: true })
// 监听本地数据变化,同步到外部
watch(localFormData, (newValue) => {
emit('update:modelValue', { ...newValue })
}, { deep: true })
// 可用的发信任务列表
const availableTasks = ref<Array<{ id: number, name: string }>>([])
// 常用的 Cron 表达式模板
const cronTemplates = [
{ label: '每分钟', value: '* * * * *' },
{ label: '每5分钟', value: '*/5 * * * *' },
{ label: '每小时', value: '0 * * * *' },
{ label: '每天凌晨2点', value: '0 2 * * *' },
{ label: '每周一凌晨2点', value: '0 2 * * 1' },
{ label: '每月1号凌晨2点', value: '0 2 1 * *' }
]
// 加载可用的发信任务
const loadAvailableTasks = async () => {
try {
const rsp = await request.get('/sendtasks/list', { params: { page: 1, size: 100 } })
availableTasks.value = rsp.data.data.lists.map((task: any) => ({
id: task.id,
name: task.name
}))
} catch (error) {
console.error('加载发信任务失败:', error)
}
}
// 应用 Cron 模板
const applyCronTemplate = (template: string) => {
localFormData.cron_expression = template
}
// 提交表单
const handleSubmit = () => {
emit('submit')
}
// 取消操作
const handleCancel = () => {
emit('cancel')
}
// 组件挂载时加载数据
loadAvailableTasks()
</script>
<template>
<div class="space-y-3">
<div class="space-y-1">
<Label for="name" class="text-sm">定时消息名称</Label>
<Input id="name" v-model="localFormData.name" placeholder="请输入定时消息名称" class="h-8" />
</div>
<div class="space-y-1">
<Label for="task_id" class="text-sm">关联发信任务</Label>
<Select v-model="localFormData.task_id">
<SelectTrigger class="h-8">
<SelectValue placeholder="选择要关联的发信任务" />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectItem v-for="task in availableTasks" :key="task.id" :value="String(task.id)">
{{ task.name }}
</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
</div>
<div class="space-y-1">
<Label for="cron_expression" class="text-sm">Cron表达式</Label>
<Input id="cron_expression" v-model="localFormData.cron_expression" placeholder="请输入Cron表达式,如: 0 2 * * *" class="h-8" />
<div class="text-xs text-gray-500">
<p class="mb-1">常用模板</p>
<div class="flex flex-wrap gap-1">
<Button v-for="template in cronTemplates" :key="template.value" size="sm" variant="outline"
@click="applyCronTemplate(template.value)" class="h-6 px-2 text-xs">
{{ template.label }}
</Button>
</div>
</div>
</div>
<div class="space-y-1">
<Label for="title" class="text-sm">标题</Label>
<Input id="title" v-model="localFormData.title" placeholder="请输入定时消息标题" class="h-8" />
</div>
<div class="space-y-1">
<Label for="content" class="text-sm">内容</Label>
<Textarea id="content" v-model="localFormData.content" placeholder="请输入定时消息内容" rows="2" class="min-h-[60px] resize-none" />
</div>
<div class="space-y-1">
<Label for="url" class="text-sm">url可选</Label>
<Input id="url" v-model="localFormData.url" placeholder="请输入定时消息描述" class="h-8" />
</div>
<div class="flex justify-end space-x-2 pt-2">
<Button variant="outline" @click="handleCancel" size="sm" :disabled="loading">
取消
</Button>
<Button @click="handleSubmit" size="sm" :disabled="loading">
{{ mode === 'add' ? '创建定时消息' : '更新定时消息' }}
</Button>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({
name: 'CronMessageForm'
})
</script>