<template>
  <div class="jobIndex">
    <basic-container>
      <avue-crud
        ref="crud"
        :page.sync="page"
        v-model="form"
        :data="tableData"
        :table-loading="tableLoading"
        :option="tableOption"
        @on-load="getList"
        @row-save="save"
        @row-update="update"
        @refresh-change="refreshChange"
        @size-change="sizeChange"
        @current-change="currentChange"
        @search-change="handleFilter"
        @search-reset="handleSearchReset"
      >
        <template slot-scope="scope" slot="jobStatus">
          <div v-if="scope.row.jobStatus === '1'">
            <el-tag type="info">{{
              getDicNameJobStatus(scope.row.jobStatus)
            }}</el-tag>
          </div>
          <div v-else-if="scope.row.jobStatus === '2'">
            <el-tag type="success">{{
              getDicNameJobStatus(scope.row.jobStatus)
            }}</el-tag>
          </div>
          <div v-else-if="scope.row.jobStatus === '3'">
            <el-tag type="danger">{{
              getDicNameJobStatus(scope.row.jobStatus)
            }}</el-tag>
          </div>
        </template>
        <template slot-scope="scope" slot="jobExecuteStatus">
          <div v-if="scope.row.jobExecuteStatus === '0'">
            <el-tag type="success">{{
              getDicNameJobExecuteStatus(scope.row.jobExecuteStatus)
            }}</el-tag>
          </div>
          <div v-else>
            <el-tag type="danger">{{
              getDicNameJobExecuteStatus(scope.row.jobExecuteStatus)
            }}</el-tag>
          </div>
        </template>
        <template slot="cronExpressionForm" slot-scope="scope">
          <div class="cron">
            <el-popover v-model="cronPopover">
              <cron
                i18n="cn"
                @change="changeCron"
                @close="cronPopover = false"
              />
              <el-input
                slot="reference"
                v-model="form.cronExpression"
                placeholder="请输入定时策略"
                @click="cronPopover = true"
              />
            </el-popover>
          </div>
        </template>
        <template slot="menuLeft">
          <el-button
            v-if="permissions.job_sys_job_add"
            type="primary"
            @click="handleAdd"
          >
            新建任务
          </el-button>
          <el-tooltip content="暂停全部运行状态的定时任务" placement="top">
            <el-button
              v-if="permissions.job_sys_job_shutdown_job"
              type="warning"
              @click="shutdownJobs"
            >
              暂停全部任务
            </el-button>
          </el-tooltip>
          <el-tooltip content="启动全部暂停状态的定时任务" placement="top">
            <el-button
              v-if="permissions.job_sys_job_start_job"
              type="success"
              @click="startJobs"
            >
              启动全部任务
            </el-button>
          </el-tooltip>
          <el-tooltip content="谨慎使用" placement="top">
            <el-button
              v-if="permissions.job_sys_job_refresh_job"
              type="danger"
              @click="refreshJobs"
              >重置全部任务
            </el-button>
          </el-tooltip>
        </template>
        <template slot="menu" slot-scope="scope">
          <el-button
            type="text"
            icon="el-icon-info"
            @click="handleJobLog(scope.row)"
            >日志
          </el-button>
          <el-button
            v-if="permissions.job_sys_job_start_job"
            type="text"
            icon="el-icon-caret-right"
            @click="handleStartJob(scope.row)"
            >启动
          </el-button>

          <el-button
            v-if="permissions.job_sys_job_shutdown_job"
            type="text"
            icon="el-icon-error"
            @click="handleShutDownJob(scope.row)"
            >暂停
          </el-button>
          <el-button
            v-if="permissions.job_sys_job_edit"
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row, scope.index)"
            >修改
          </el-button>
          <el-button
            v-if="permissions.job_sys_job_run_job"
            type="text"
            icon="el-icon-s-promotion"
            @click="handleRunJob(scope.row)"
            >执行
          </el-button>
          <el-button
            v-if="permissions.job_sys_job_del"
            type="text"
            icon="el-icon-delete"
            @click="handleDelete(scope.row, scope.index)"
            >删除
          </el-button>
        </template>
      </avue-crud>
    </basic-container>
    <jobLog v-if="dialogFormVisible" ref="logRef"></jobLog>
  </div>
</template>

<script>
import {
  addObj,
  delObj,
  fetchList,
  isValidTaskName,
  putObj,
  refreshJobsRa,
  runJobRa,
  shutDownJobRa,
  shutdownJobsRa,
  startJobRa,
  startJobsRa,
} from "@/api/daemon/sys-job";
import { tableOption } from "@/const/crud/daemon/sys-job";
import { remote } from "@/api/admin/dict";
import { mapGetters } from "vuex";
import { cron } from "vue-cron";
import jobLog from "./job-log";

export default {
  name: "jobIndex",
  components: { cron, jobLog },
  data() {
    return {
      form: {},
      cronPopover: false,
      queryParams: {}, // 全局检索条件
      tableData: [],
      dialogFormVisible: false,
      jobId: "",
      page: {
        total: 0, // 总页数
        currentPage: 1, // 当前页数
        pageSize: 10, // 每页显示多少条,
      },
      tableLoading: false,
      tableOption: tableOption,
      JobExecuteStatusDicCache: [],
      JobStatusDicCache: [],
    };
  },
  computed: {
    ...mapGetters(["permissions"]),
  },
  mounted: function () {
    this.getDicJobExecuteStatusCache("job_execute_status"); // 获取定时任务运行时状态
    this.getDicJobStatusCache("job_status"); // 获取定时任务状态
  },
  methods: {
    changeCron(val) {
      this.form.cronExpression = val;
    },
    /**
     * 定时任务分页查询
     */
    getList() {
      this.tableLoading = true;
      fetchList(
        Object.assign(
          {
            descs: "create_time",
            current: this.page.currentPage,
            size: this.page.pageSize,
          },
          this.queryParams
        )
      ).then((response) => {
        this.tableData = response.data.data.records;
        this.page.total = response.data.data.total;
        this.tableLoading = false;
      });
    },
    /**
     * 清除全局检索条件
     */
    handleSearchReset() {
      this.queryParams = {};
    },
    /**
     * 定时任务检索查询分页查询
     */
    handleFilter(params, done) {
      this.queryParams = params;
      this.page.currentPage = 1;
      this.getList(this.page);
      done();
    },
    /**
     * 启动定时任务
     */
    handleStartJob(row) {
      const jobStatus = row.jobStatus;
      if (jobStatus === "1" || jobStatus === "3") {
        this.$confirm(
          "即将发布或启动(任务名称:" + row.jobName + "), 是否继续?",
          "提示",
          {
            confirmButtonText: "确定",
            cancelButtonText: "取消",
            type: "warning",
          }
        ).then(() => {
          startJobRa(row.jobId)
            .then((response) => {
              const code = response.data.code;
              if (code === 0) {
                this.$notify({
                  title: "成功",
                  message: "启动成功",
                  type: "success",
                });
                this.refreshChange();
              }
            })
            .catch(() => {
              this.$notify.error({
                title: "错误",
                message: "启动失败",
              });
            });
        });
      } else {
        this.$notify.error({
          title: "错误",
          message: "定时任务已运行",
        });
      }
    },
    /**
     * 执行定时任务
     */
    handleRunJob(row) {
      this.$confirm(
        "立刻执行一次任务(任务名称:" + row.jobName + "), 是否继续?",
        "提示",
        {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
        }
      ).then(() => {
        runJobRa(row.jobId)
          .then((response) => {
            const code = response.data.code;
            if (code === 0) {
              this.$notify({
                title: "成功",
                message: "执行成功",
                type: "success",
              });
              this.refreshChange();
            }
          })
          .catch(() => {
            this.$notify.error({
              title: "错误",
              message: "执行失败",
            });
          });
      });
    },
    handleAdd() {
      this.$refs.crud.rowAdd();
    },
    handleUpdate(row, index) {
      const jobStatus = row.jobStatus;
      if (jobStatus === "1" || jobStatus === "3") {
        this.$refs.crud.rowEdit(row, index);
      } else {
        this.$notify.error({
          title: "错误",
          message: "运行中定时任务不可修改，请先暂停后操作",
        });
      }
    },
    /**
     * 暂停定时任务
     */
    handleShutDownJob(row) {
      const jobStatus = row.jobStatus;
      if (jobStatus === "2") {
        this.$confirm(
          "即将暂停(任务名称:" + row.jobName + "), 是否继续?",
          "提示",
          {
            confirmButtonText: "确定",
            cancelButtonText: "取消",
            type: "warning",
          }
        ).then(() => {
          shutDownJobRa(row.jobId)
            .then((response) => {
              const code = response.data.code;
              if (code === 0) {
                this.getList(this.page);
                this.$notify({
                  title: "成功",
                  message: "暂停成功",
                  type: "success",
                });
              }
              this.refreshChange();
            })
            .catch(() => {
              this.$notify.error({
                title: "错误",
                message: "暂停失败",
              });
            });
        });
      } else {
        this.$notify.error({
          title: "错误",
          message: "已暂停，不要重复操作",
        });
      }
    },
    /**
     * 刷新回调
     */
    refreshChange() {
      this.getList(this.page);
    },
    sizeChange(pageSize) {
      this.page.pageSize = pageSize;
    },
    currentChange(current) {
      this.page.currentPage = current;
    },
    shutdownJobs() {
      this.$confirm("即将暂停全部运行中定时任务, 是否继续?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      }).then(() => {
        shutdownJobsRa()
          .then((response) => {
            const code = response.data.code;
            const data = response.data.data;
            if (code === 0) {
              this.getList(this.page);
              this.$notify.success(data);
            } else {
              this.$notify.error("暂停失败");
            }
          })
          .catch(() => {
            this.$notify.error("暂停失败");
          });
      });
    },
    /**
     * 启动全部暂停定时任务
     */
    startJobs() {
      this.$confirm("即将启动全部暂定中定时任务, 是否继续?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      }).then(() => {
        startJobsRa()
          .then((response) => {
            const code = response.data.code;
            if (code === 0) {
              this.getList(this.page);
              this.$notify.success("启动成功");
            } else {
              this.$notify.error("启动失败");
            }
          })
          .catch(() => {
            this.$notify.error("启动失败");
          });
      });
    },
    /**
     * 刷新定时任务
     */
    refreshJobs() {
      this.$confirm("即将刷新全部定时任务, 是否继续?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      }).then(() => {
        refreshJobsRa()
          .then((response) => {
            const code = response.data.code;
            if (code === 0) {
              this.getList(this.page);
              this.$notify.success("重置成功");
            } else {
              this.$notify.error("重置失败");
            }
          })
          .catch(() => {
            this.$notify.error("重置失败");
          });
      });
    },
    /**
     * 新增定时任务持久化处理
     */
    save(row, done, loading) {
      isValidTaskName({
        jobName: row.jobName,
        jobGroup: row.jobGroup,
      })
        .then((response) => {
          const result = response.data.code;
          if (result !== 0) {
            this.$notify.error("任务名称与任务组重复，请确认后重新添加");
          } else {
            addObj(row)
              .then(() => {
                this.$notify.success("创建成功");
                this.getList(this.page);
              })
              .catch(() => {
                loading();
              });
          }
          done();
        })
        .catch(() => {
          loading();
        });
    },
    /**
     * 更新定时任务持久化处理
     */
    update(row, index, done, loading) {
      putObj(row)
        .then(() => {
          this.getList(this.page);
          done();
          this.$notify.success("修改成功");
        })
        .catch(() => {
          loading();
        });
    },
    /**
     * 删除定时任务持久化处理
     */
    handleDelete(row) {
      const jobStatus = row.jobStatus;
      if (jobStatus === "1" || jobStatus === "3") {
        this.$confirm(
          "是否确认删除(任务名称:" + row.jobName + "), 是否继续?删除后不可恢复",
          "警告",
          {
            confirmButtonText: "确定",
            cancelButtonText: "取消",
            type: "warning",
          }
        )
          .then(function () {
            return delObj(row.jobId);
          })
          .then(() => {
            this.getList(this.page);
            this.$notify.success("删除成功");
          })
          .catch(function () {});
      } else {
        this.$notify.error("运行中定时任务不可删除，请先暂停后操作");
      }
    },
    handleJobLog(row) {
      this.dialogFormVisible = true;
      this.$nextTick(() => {
        this.$refs.logRef.getJobLog(row);
      });
    },
    /**
     * 获取字典显示名称并缓存
     */
    getDicJobExecuteStatusCache(type) {
      remote(type).then((response) => {
        const code = response.data.code;
        if (code === 0) {
          const _data = response.data.data;
          this.JobExecuteStatusDicCache = _data;
        }
      });
    },
    /**
     * 获取字典显示名称并缓存
     */
    getDicJobStatusCache(type) {
      remote(type).then((response) => {
        const code = response.data.code;
        if (code === 0) {
          const _data = response.data.data;
          this.JobStatusDicCache = _data;
        }
      });
    },
    /**
     * 获取字典定时任务执行状态字典值显示名称
     */
    getDicNameJobExecuteStatus(value) {
      let re = "";
      this.JobExecuteStatusDicCache.forEach((obj) => {
        if (obj.value === value) {
          re = obj.label;
          return;
        }
      });
      return re;
    },
    /**
     * 获取字典定时任务状态字典值显示名称
     */
    getDicNameJobStatus(value) {
      let re = "";
      this.JobStatusDicCache.forEach((obj) => {
        if (obj.value === value) {
          re = obj.label;
          return;
        }
      });
      return re;
    },
  },
};
</script>

<style lang="scss" scoped></style>
