| 对比新文件 |
| | |
| | | <template> |
| | | <div class="cron-generator"> |
| | | <el-form :inline="true" label-width="100px"> |
| | | <el-form-item label="定时类型" prop="type"> |
| | | <el-select v-model="type" @change="handleTypeChange" style="width: 200px"> |
| | | <el-option label="每月" value="monthly"/> |
| | | <el-option label="每周" value="weekly"/> |
| | | <el-option label="每天" value="daily"/> |
| | | <el-option label="每小时" value="hourly"/> |
| | | <el-option label="每隔N分钟" value="interval"/> |
| | | </el-select> |
| | | </el-form-item> |
| | | |
| | | <el-form-item v-if="type==='monthly'" label="日期" prop="day"> |
| | | <el-input-number |
| | | v-model="day" |
| | | :min="1" |
| | | :max="31" |
| | | controls-position="right" |
| | | style="width: 120px" |
| | | /> |
| | | <span style="margin-left: 10px">日</span> |
| | | </el-form-item> |
| | | |
| | | <el-form-item v-if="type==='weekly'" label="星期" prop="weekDay"> |
| | | <el-select v-model="weekDay" style="width: 120px"> |
| | | <el-option |
| | | v-for="(w, i) in weekList" |
| | | :key="i" |
| | | :label="w.label" |
| | | :value="w.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | |
| | | <el-form-item |
| | | v-if="['monthly','weekly','daily'].includes(type)" |
| | | label="时间" |
| | | prop="time" |
| | | > |
| | | <el-time-picker |
| | | v-model="time" |
| | | format="HH:mm" |
| | | value-format="HH:mm" |
| | | placeholder="选择时间" |
| | | style="width: 120px" |
| | | /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item v-if="type==='interval'" label="间隔" prop="interval"> |
| | | <el-input-number |
| | | v-model="interval" |
| | | :min="1" |
| | | :max="59" |
| | | controls-position="right" |
| | | style="width: 120px" |
| | | /> |
| | | <span style="margin-left: 10px">分钟</span> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <el-alert |
| | | :title="'生成的 cron 表达式: ' + cronValue" |
| | | type="info" |
| | | show-icon |
| | | style="margin-top: 15px" |
| | | /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | props: { |
| | | value: { |
| | | type: String, |
| | | default: '' |
| | | } |
| | | }, |
| | | data() { |
| | | return { |
| | | type: 'daily', |
| | | day: 1, |
| | | weekDay: 1, |
| | | time: '00:00', |
| | | interval: 5, |
| | | weekList: [ |
| | | {label: '周日', value: 0}, |
| | | {label: '周一', value: 1}, |
| | | {label: '周二', value: 2}, |
| | | {label: '周三', value: 3}, |
| | | {label: '周四', value: 4}, |
| | | {label: '周五', value: 5}, |
| | | {label: '周六', value: 6}, |
| | | ] |
| | | }; |
| | | }, |
| | | computed: { |
| | | cronValue: { |
| | | get() { |
| | | return this.value; |
| | | }, |
| | | set(val) { |
| | | this.$emit('input', val); |
| | | } |
| | | } |
| | | }, |
| | | watch: { |
| | | type() { this.generateCron(); }, |
| | | day() { this.generateCron(); }, |
| | | weekDay() { this.generateCron(); }, |
| | | time() { this.generateCron(); }, |
| | | interval() { this.generateCron(); }, |
| | | value(newVal) { |
| | | // 外部 value 变化时,自动解析 |
| | | this.setCron(newVal); |
| | | }, |
| | | }, |
| | | methods: { |
| | | setCron(cron) { |
| | | console.log("接收到 cron 值:", cron); |
| | | if (!cron || typeof cron !== 'string') { |
| | | return; |
| | | } |
| | | |
| | | const parts = cron.split(' '); |
| | | if (parts.length < 6) return; |
| | | |
| | | const second = parts[0]; |
| | | const minute = parts[1]; |
| | | const hour = parts[2]; |
| | | const day = parts[3]; |
| | | const weekday = parts[5]; |
| | | |
| | | if (minute.startsWith('*/')) { |
| | | this.type = 'interval'; |
| | | this.interval = parseInt(minute.split('/')[1]); |
| | | } else if (day !== '*' && day !== '?') { |
| | | this.type = 'monthly'; |
| | | this.day = parseInt(day); |
| | | this.time = `${hour.padStart(2, '0')}:${minute.padStart(2, '0')}`; |
| | | } else if (weekday !== '*' && weekday !== '?') { |
| | | this.type = 'weekly'; |
| | | this.weekDay = parseInt(weekday); |
| | | this.time = `${hour.padStart(2, '0')}:${minute.padStart(2, '0')}`; |
| | | } else if (hour !== '*') { |
| | | this.type = 'daily'; |
| | | this.time = `${hour.padStart(2, '0')}:${minute.padStart(2, '0')}`; |
| | | } else { |
| | | this.type = 'hourly'; |
| | | } |
| | | this.generateCron(); |
| | | }, |
| | | |
| | | |
| | | resetToDefault() { |
| | | this.type = 'daily'; |
| | | this.day = 1; |
| | | this.weekDay = 1; |
| | | this.time = '00:00'; |
| | | this.interval = 5; |
| | | this.generateCron(); |
| | | }, |
| | | |
| | | handleTypeChange() { |
| | | if (this.type === 'monthly' && (this.day < 1 || this.day > 31)) { |
| | | this.day = 1; |
| | | } |
| | | if (this.type === 'interval' && (this.interval < 1 || this.interval > 59)) { |
| | | this.interval = 5; |
| | | } |
| | | this.generateCron(); |
| | | }, |
| | | |
| | | generateCron() { |
| | | console.log("生成 cron 表达式,类型:", this.type); |
| | | let hour = 0; |
| | | let minute = 0; |
| | | |
| | | if (this.time) { |
| | | [hour, minute] = this.time.split(':').map(Number); |
| | | } else { |
| | | this.time = '00:00'; |
| | | } |
| | | |
| | | switch(this.type) { |
| | | case 'monthly': |
| | | this.cronValue = `0 ${minute} ${hour} ${this.day} * ?`; // 添加秒位和?号 |
| | | break; |
| | | case 'weekly': |
| | | this.cronValue = `0 ${minute} ${hour} ? * ${this.weekDay}`; // 添加秒位和?号 |
| | | break; |
| | | case 'daily': |
| | | this.cronValue = `0 ${minute} ${hour} * * ?`; // 添加秒位和?号 |
| | | break; |
| | | case 'hourly': |
| | | this.cronValue = `0 ${minute} * * * ?`; // 添加秒位和?号 |
| | | break; |
| | | case 'interval': |
| | | // 间隔分钟需要特殊处理,转换为秒级间隔 |
| | | this.cronValue = `0 */${this.interval} * * * ?`; |
| | | break; |
| | | default: |
| | | this.cronValue = '0 * * * * ?'; |
| | | } |
| | | console.log("生成结果:", this.cronValue); |
| | | } |
| | | }, |
| | | mounted() { |
| | | this.generateCron(); |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .cron-generator { |
| | | padding: 15px; |
| | | border: 1px solid #ebeef5; |
| | | border-radius: 4px; |
| | | background-color: #f8f9fa; |
| | | } |
| | | </style> |
| 对比新文件 |
| | |
| | | :task-config.vue |
| | | <template> |
| | | <el-bus-crud ref="crud" v-bind="tableConfig"> |
| | | <!-- 不再需要自定义插槽 --> |
| | | </el-bus-crud> |
| | | </template> |
| | | |
| | | <script> |
| | | // 不再需要导入 CronGenerator,因为现在通过全局注册使用 |
| | | |
| | | export default { |
| | | data() { |
| | | return { |
| | | tableConfig: { |
| | | defaultForm: { |
| | | taskName: '', |
| | | aiParams: '', |
| | | cron: '', |
| | | isEnabled: false |
| | | }, |
| | | url: 'flower/api/aiTaskConfig/list', |
| | | newUrl: 'flower/api/aiTaskConfig/new', |
| | | editUrl: 'flower/api/aiTaskConfig/edit', |
| | | deleteUrl: 'flower/api/aiTaskConfig/delete', |
| | | dialogNeedRequest: false, |
| | | persistSelection: true, |
| | | columns: [ |
| | | { type: 'selection' }, |
| | | { label: '任务名称', prop: 'taskName' }, |
| | | { label: 'AI参数', prop: 'aiParams' }, |
| | | { label: 'cron表达式', prop: 'cron' }, |
| | | { |
| | | label: '启用/禁用', |
| | | formatter: (row) => ( |
| | | <el-switch |
| | | value={row.isEnabled} |
| | | onChange={(val) => this.onEnabledChange(row, val)} |
| | | ></el-switch> |
| | | ), |
| | | minWidth: 120, |
| | | fixed: 'right', |
| | | }, |
| | | ], |
| | | searchForm: [ |
| | | { |
| | | type: 'row', |
| | | items: [ |
| | | { label: '任务名称', id: 'taskName', type: 'input' }, |
| | | { |
| | | label: '启用/禁用', |
| | | id: 'isEnabled', |
| | | type: 'bus-select-dict', |
| | | default: '1', |
| | | el: { |
| | | code: 'USER_ENABLED_OR_DISABLED', |
| | | clearable: true, |
| | | style: 'width:100%', |
| | | }, |
| | | }, |
| | | ] |
| | | } |
| | | ], |
| | | form: [ |
| | | { label: '任务名称', id: 'taskName', type: 'input', rules: { required: true, message: '请输入任务名称', trigger: 'blur' } }, |
| | | { label: 'AI参数', id: 'aiParams', type: 'input', rules: { required: true, message: '请输入AI参数', trigger: 'blur' } }, |
| | | { |
| | | label: '定时配置', |
| | | id: 'cron', |
| | | type: 'input', |
| | | // hidden: () => true, // 改为函数形式 |
| | | rules: { required: true } |
| | | }, |
| | | { label: '是否启用', id: 'isEnabled', type: 'switch' } |
| | | ], |
| | | extraButtons: [], |
| | | headerButtons: [ |
| | | { |
| | | text: '批量删除', |
| | | type: 'danger', |
| | | disabled: selected => selected.length === 0, |
| | | atClick: async (selected) => { |
| | | if (!selected.length) return |
| | | |
| | | try { |
| | | await this.$elBusUtil.confirm(`确定要批量删除这${selected.length}个任务吗?`) |
| | | const ids = selected.map(item => item.id) |
| | | await this.$elBusHttp.request('flower/api/filmTaskConfig/delete', { |
| | | method: 'post', |
| | | data: { ids } |
| | | }) |
| | | this.$refs.crud.getList() |
| | | this.$message.success('删除成功') |
| | | } catch (error) { |
| | | if (error !== 'cancel') { |
| | | this.$message.error('删除失败') |
| | | } |
| | | } |
| | | } |
| | | } |
| | | ], |
| | | extraDialogs: [ |
| | | { |
| | | title: '任务配置', |
| | | form: [ |
| | | { label: '任务名称', id: 'taskName', type: 'input', rules: { required: true, message: '请输入任务名称', trigger: 'blur' } }, |
| | | { label: 'AI参数', id: 'aiParams', type: 'input', rules: { required: true, message: '请输入AI参数', trigger: 'blur' } }, |
| | | { |
| | | label: '定时配置', |
| | | id: 'cron', |
| | | component: 'cron-generator', // 使用组件名称字符串 |
| | | rules: { required: true, message: '请配置定时规则', trigger: 'change' }, |
| | | // hidden: () => false, // 明确显示 |
| | | props: { |
| | | value: '{{cron}}' |
| | | }, |
| | | on: { |
| | | input: (value, form) => { |
| | | form.cron = value; |
| | | } |
| | | } |
| | | }, |
| | | { label: '是否启用', id: 'isEnabled', type: 'switch' } |
| | | ], |
| | | atConfirm: async (form) => { |
| | | const url = form.id ? this.tableConfig.editUrl : this.tableConfig.newUrl; |
| | | const { code } = await this.$elBusHttp.request(url, { |
| | | method: 'post', |
| | | data: form |
| | | }); |
| | | if (code === 0) { |
| | | this.$message.success('保存成功'); |
| | | this.$refs.crud.getList(); |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | } |
| | | ] |
| | | } |
| | | } |
| | | }, |
| | | head() { |
| | | return { |
| | | title: '模型任务管理', |
| | | } |
| | | }, |
| | | methods: { |
| | | onEnabledChange(row, newValue) { |
| | | const url = 'flower/api/aiTaskConfig/isEnable' |
| | | const text = newValue ? '启用' : '禁用' |
| | | this.$elBusUtil |
| | | .confirm(`确定要${text}这个模型任务吗?`) |
| | | .then(async () => { |
| | | const { code } = await this.$elBusHttp.request(url, { |
| | | method: 'post', |
| | | data: { |
| | | id: row.id, |
| | | isEnabled: newValue |
| | | } |
| | | }) |
| | | |
| | | if (code === 0) { |
| | | this.$message.success(`${text}成功`) |
| | | this.$refs.crud.getList() |
| | | } |
| | | }) |
| | | .catch(() => { |
| | | row.isEnabled = !newValue |
| | | }) |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | | /* 可以添加一些样式调整 */ |
| | | </style> |
| 对比新文件 |
| | |
| | | :task-config.vue |
| | | <template> |
| | | <el-bus-crud ref="crud" v-bind="tableConfig"> |
| | | <!-- 不再需要自定义插槽 --> |
| | | </el-bus-crud> |
| | | </template> |
| | | |
| | | <script> |
| | | // 不再需要导入 CronGenerator,因为现在通过全局注册使用 |
| | | |
| | | export default { |
| | | data() { |
| | | return { |
| | | tableConfig: { |
| | | defaultForm: { |
| | | taskName: '', |
| | | aiParams: '', |
| | | cron: '', |
| | | isEnabled: false |
| | | }, |
| | | url: 'flower/api/filmTaskConfig/list', |
| | | newUrl: 'flower/api/filmTaskConfig/new', |
| | | editUrl: 'flower/api/filmTaskConfig/edit', |
| | | deleteUrl: 'flower/api/filmTaskConfig/delete', |
| | | dialogNeedRequest: false, |
| | | persistSelection: true, |
| | | hasNew:false, |
| | | hasEdit:false, |
| | | hasOperation:false, |
| | | columns: [ |
| | | { type: 'selection' }, |
| | | { label: '任务名称', prop: 'taskName' }, |
| | | { label: 'AI参数', prop: 'aiParams' }, |
| | | { label: 'cron表达式', prop: 'cron' }, |
| | | { |
| | | label: '启用/禁用', |
| | | formatter: (row) => ( |
| | | <el-switch |
| | | value={row.isEnabled} |
| | | onChange={(val) => this.onEnabledChange(row, val)} |
| | | ></el-switch> |
| | | ), |
| | | minWidth: 120, |
| | | fixed: 'right', |
| | | }, |
| | | ], |
| | | searchForm: [ |
| | | { |
| | | type: 'row', |
| | | items: [ |
| | | { label: '任务名称', id: 'taskName', type: 'input' }, |
| | | { |
| | | label: '启用/禁用', |
| | | id: 'isEnabled', |
| | | type: 'bus-select-dict', |
| | | default: '1', |
| | | el: { |
| | | code: 'USER_ENABLED_OR_DISABLED', |
| | | clearable: true, |
| | | style: 'width:100%', |
| | | }, |
| | | }, |
| | | ] |
| | | } |
| | | ], |
| | | form: [ |
| | | // { label: '任务名称', id: 'taskName', type: 'input', rules: { required: true, message: '请输入任务名称', trigger: 'blur' } }, |
| | | // { label: 'AI参数', id: 'aiParams', type: 'input', rules: { required: true, message: '请输入AI参数', trigger: 'blur' } }, |
| | | // { |
| | | // label: '定时配置', |
| | | // id: 'cron', |
| | | // type: 'input', |
| | | // // hidden: () => true, // 改为函数形式 |
| | | // rules: { required: true } |
| | | // }, |
| | | // { label: '是否启用', id: 'isEnabled', type: 'switch' } |
| | | ], |
| | | extraButtons: [], |
| | | headerButtons: [ |
| | | { |
| | | text: '批量删除', |
| | | type: 'danger', |
| | | disabled: selected => selected.length === 0, |
| | | atClick: async (selected) => { |
| | | if (!selected.length) return |
| | | |
| | | try { |
| | | await this.$elBusUtil.confirm(`确定要批量删除这${selected.length}个任务吗?`) |
| | | const ids = selected.map(item => item.id) |
| | | await this.$elBusHttp.request('flower/api/filmTaskConfig/delete/batch', { |
| | | method: 'post', |
| | | data: { ids } |
| | | }) |
| | | this.$refs.crud.getList() |
| | | this.$message.success('删除成功') |
| | | } catch (error) { |
| | | if (error !== 'cancel') { |
| | | this.$message.error('删除失败') |
| | | } |
| | | } |
| | | } |
| | | } |
| | | ], |
| | | extraDialogs: [ |
| | | { |
| | | title: '任务配置', |
| | | form: [ |
| | | { label: '任务名称', id: 'taskName', type: 'input', rules: { required: true, message: '请输入任务名称', trigger: 'blur' } }, |
| | | { label: 'AI参数', id: 'aiParams', type: 'input', rules: { required: true, message: '请输入AI参数', trigger: 'blur' } }, |
| | | { |
| | | label: '定时配置', |
| | | id: 'cron', |
| | | component: 'cron-generator', // 使用组件名称字符串 |
| | | rules: { required: true, message: '请配置定时规则', trigger: 'change' }, |
| | | // hidden: () => false, // 明确显示 |
| | | props: { |
| | | value: '{{cron}}' |
| | | }, |
| | | on: { |
| | | input: (value, form) => { |
| | | form.cron = value; |
| | | } |
| | | } |
| | | }, |
| | | { label: '是否启用', id: 'isEnabled', type: 'switch' } |
| | | ], |
| | | atConfirm: async (form) => { |
| | | const url = form.id ? this.tableConfig.editUrl : this.tableConfig.newUrl; |
| | | const { code } = await this.$elBusHttp.request(url, { |
| | | method: 'post', |
| | | data: form |
| | | }); |
| | | if (code === 0) { |
| | | this.$message.success('保存成功'); |
| | | this.$refs.crud.getList(); |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | } |
| | | ] |
| | | } |
| | | } |
| | | }, |
| | | head() { |
| | | return { |
| | | title: '模型任务管理', |
| | | } |
| | | }, |
| | | methods: { |
| | | onEnabledChange(row, newValue) { |
| | | const url = 'flower/api/aiTaskConfig/isEnable' |
| | | const text = newValue ? '启用' : '禁用' |
| | | this.$elBusUtil |
| | | .confirm(`确定要${text}这个模型任务吗?`) |
| | | .then(async () => { |
| | | const { code } = await this.$elBusHttp.request(url, { |
| | | method: 'post', |
| | | data: { |
| | | id: row.id, |
| | | isEnabled: newValue |
| | | } |
| | | }) |
| | | |
| | | if (code === 0) { |
| | | this.$message.success(`${text}成功`) |
| | | this.$refs.crud.getList() |
| | | } |
| | | }) |
| | | .catch(() => { |
| | | row.isEnabled = !newValue |
| | | }) |
| | | }, |
| | | onEdit(row) { |
| | | this.$refs.crud.$refs.extraDialog[0].show(row); |
| | | }, |
| | | onNew() { |
| | | this.$refs.crud.$refs.extraDialog[0].show(this.tableConfig.defaultForm); |
| | | } |
| | | }, |
| | | mounted() { |
| | | // 配置按钮触发 |
| | | this.tableConfig.headerButtons.push( |
| | | { |
| | | text: '新增', |
| | | type: 'primary', |
| | | atClick: () => this.onNew() |
| | | } |
| | | ); |
| | | |
| | | // 修改列配置添加操作按钮 |
| | | this.tableConfig.columns.push({ |
| | | label: '操作', |
| | | fixed: 'right', |
| | | width: 120, |
| | | formatter: (row) => ( |
| | | <el-button type="text" onClick={() => this.onEdit(row)}>编辑</el-button> |
| | | ) |
| | | }); |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | | /* 可以添加一些样式调整 */ |
| | | </style> |