From aabe2d9c0d656f6dbd0273a711c9765acbf51444 Mon Sep 17 00:00:00 2001
From: cloudroam <cloudroam>
Date: 星期六, 05 七月 2025 11:25:58 +0800
Subject: [PATCH] add:corn 和任务管理

---
 components/cron-generator.vue    |  221 ++++++++++++++++++++
 pages/regular/content-config.vue |  177 ++++++++++++++++
 pages/regular/task-config.vue    |  206 ++++++++++++++++++
 3 files changed, 604 insertions(+), 0 deletions(-)

diff --git a/components/cron-generator.vue b/components/cron-generator.vue
new file mode 100644
index 0000000..0fe680a
--- /dev/null
+++ b/components/cron-generator.vue
@@ -0,0 +1,221 @@
+<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>
diff --git a/pages/regular/content-config.vue b/pages/regular/content-config.vue
new file mode 100644
index 0000000..760a228
--- /dev/null
+++ b/pages/regular/content-config.vue
@@ -0,0 +1,177 @@
+: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>
diff --git a/pages/regular/task-config.vue b/pages/regular/task-config.vue
new file mode 100644
index 0000000..ffc4e4a
--- /dev/null
+++ b/pages/regular/task-config.vue
@@ -0,0 +1,206 @@
+: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>

--
Gitblit v1.9.3