cloudroam
2025-07-05 aabe2d9c0d656f6dbd0273a711c9765acbf51444
add:corn 和任务管理
已添加3个文件
604 ■■■■■ 文件已修改
components/cron-generator.vue 221 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/regular/content-config.vue 177 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/regular/task-config.vue 206 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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>
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>
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>