<template>
  <div>
    <Panel title="任务查询">
      <template slot="buttons">
        <el-button class="blue" @click="pageTable.handleLoad()" icon="el-icon-fa-search">查询</el-button>
        <el-button class="yellow" @click="pageTable.handleReset()" icon="el-icon-fa-reply-all">重置</el-button>
      </template>

      <el-form ref="form" :model="pageTable.param">
        <el-row>
          <el-col :lg='4' :sm='12'>
            <el-form-item label="任务名称">
              <el-input v-model="pageTable.param.name"></el-input>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
    </Panel>
    <Panel title="任务列表">
      <template slot="buttons">
        <el-button class="green" @click="handlerMultiStart" icon="el-icon-fa-play" :disabled="selection.length === 0">批量启动
        </el-button>
        <el-button class="yellow" @click="handlerMultiStop" icon="el-icon-fa-pause" :disabled="selection.length === 0">批量停止
        </el-button>
        <el-button class="blue" @click="handlerAdd" icon="el-icon-fa-random" v-if="cluster.Mode">视图切换</el-button>
        <el-button class="green" @click="handlerAdd" icon="el-icon-fa-plus">新增</el-button>
      </template>


      <el-table :data="pageTable.data" ref="table" border v-loading="pageTable.isLoading" element-loading-spinner="el-icon-loading"
                height="calc(100vh - 280px)" @selection-change="selectionChange">
        <el-table-column type="selection" label="#"></el-table-column>
        <el-table-column prop="name" label="任务名称"></el-table-column>
        <el-table-column prop="label" label="执行任务"></el-table-column>
        <el-table-column prop="cron_expression" label="Cron表达式"></el-table-column>
        <el-table-column prop="next_execute_time" label="下次触发时间" :formatter="formatterDateTime" width="150px"></el-table-column>
        <el-table-column label="任务状态" align="center" width="100px">
          <template slot-scope="{row}">
            <el-tag v-if="row.instance" type="success">运行中</el-tag>
            <el-tag v-else type="info">停止</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="触发状态" align="center" width="100px">
          <template slot-scope="{row}">
            <el-tag v-if="row.state === '1'" type="success">运行中</el-tag>
            <el-tag v-else-if="row.state === '2'" type="info">停止</el-tag>
            <el-tag v-else-if="row.state === '3'" type="danger">异常中止</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="操作" align="center" width="300">
          <template slot-scope="{row}">
            <el-button class="green" @click="handlerStart(row.uuid)" v-if="row.state === '2' || row.state === '3'"
                       icon="el-icon-fa-play">启动
            </el-button>
            <el-button class="yellow" @click="handlerStop(row.uuid)" v-if="row.state === '1'" icon="el-icon-fa-pause">停止
            </el-button>
            <el-button class="green" @click="handlerOnce(row.uuid)" :disabled="row.state === '1' || row.instance"
                       icon="el-icon-fa-step-forward">执行
            </el-button>
            <el-button class="blue" @click="handlerView(row.uuid)" icon="el-icon-fa-eye">查看</el-button>
            <el-button class="blue" @click="handlerEdit(row.uuid)" :disabled="row.state === '1' || row.instance"
                       icon="el-icon-fa-edit">编辑
            </el-button>
            <el-button class="red" @click="handlerDelete(row.uuid)" :disabled="row.state === '1' || row.instance"
                       icon="el-icon-fa-trash">删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>
      <export-ctrl class="pull-left" @export="pageTable.handleExport($event, $refs.table)"/>
      <el-pagination background :page-size.sync="pageTable.size" :current-page.sync="pageTable.curr" :total="pageTable.total"/>
    </Panel>

    <el-dialog close-on-press-escape :title="edit.readonly? '任务查看':'任务编辑'" :visible.sync="edit.visible" width="400" append-to-body>
      <div class="dialog-button">
        <el-button class="blue" @click="handlerSave" icon="el-icon-fa-save">保存</el-button>
      </div>
      <div v-loading="edit.loading" v-if="edit.visible">
        <el-form ref="form" :model="edit.data" label-position="top">
          <el-form-item label="任务名称" prop="name" required>
            <el-input v-model="edit.data.name" :readonly="edit.readonly"></el-input>
          </el-form-item>
          <el-form-item label="任务描述" prop="description">
            <el-input v-model="edit.data.description" :readonly="edit.readonly"></el-input>
          </el-form-item>
          <el-form-item label="执行任务" prop="className" required>
            <el-select v-model="edit.data.className" :disabled="edit.readonly" filterable>
              <el-option-group v-for="group in taskList" :key="group.label" :label="group.label">
                <el-option v-for="(item, index) in group.options" :key="index"
                           :label="item.label + ' - ' + item.className.substring(item.className.lastIndexOf('.') + 1)"
                           :value="item.className">
                  <span style="float: left">{{ item.label }}</span>
                  <span style="float: right; color: #8492a6; font-size: 13px; padding-right: 5px;">
                                    {{ item.className.substring(item.className.lastIndexOf('.') + 1) }}
                                </span>
                </el-option>
              </el-option-group>
            </el-select>
          </el-form-item>
          <el-form-item label="Cron表达式" prop="cronExpression" required>
            <cron-tab :readonly="edit.readonly" v-model="edit.data.cronExpression"/>
          </el-form-item>
          <el-form-item label="任务配置" prop="config">
            <el-popover placement="top" style="position: absolute" @show="popoverShow">
              <p v-html="JSON.stringify(JSON.parse(currConfig), null, '<br/>  ')"></p>
              <div style="font-size: 18px !important; float: right" v-if="currConfig !== '{}'">
                <i class="el-icon-copy-document" style="cursor: pointer; margin-right: 10px;"
                   @click="handleClickCopyClipboard"
                   title="复制到剪贴板"/>
                <i class="el-icon-edit" style="cursor: pointer; margin-right: 10px;" @click="handleClickCopyInput"
                   title="复制到编辑框"/>
              </div>
              <el-button slot="reference" type="text" style="float: right;position: absolute;left: 55px;top: -20px;">
                <i class="el-icon-warning"/>
              </el-button>
            </el-popover>
            <el-input v-model="edit.data.config" type="textarea" rows="5" :readonly="edit.readonly"></el-input>
          </el-form-item>
          <el-form-item label="触发状态" prop="state">
            <el-radio-group v-model="edit.data.state" :disabled="edit.readonly">
              <el-radio label="1">启动</el-radio>
              <el-radio label="2">停止</el-radio>
              <!--<el-radio label="3" disabled>终止</el-radio>-->
            </el-radio-group>
          </el-form-item>
        </el-form>
        <OptionHistory v-if="edit.readonly && edit.data.uuid" :data="edit.data"></OptionHistory>
      </div>
    </el-dialog>
  </div>
</template>

<script>
  import PageTable from "@/libs/PageTable";
  import TaskMgrApi from "@/api/base/sysm/TaskMgrApi";
  import OptionHistory from "@/common/OptionHistory";
  import CronTab from "@/common/CronTab";

  const default_data = {
    uuid: null,
    name: '',
    description: '',
    className: '',
    state: '2',
    config: '{}'
  };
  export default {
    name: '',
    components: {OptionHistory, CronTab},
    data() {

      return {
        pageTable: new PageTable({
          doLoad: TaskMgrApi.query,
          param: {},
          autoLoad: true
        }),
        edit: {
          visible: false,
          loading: false,
          readonly: false,
          data: Object.assign({}, default_data)
        },
        taskList: [],
        selection: [],
        currConfig: '{}',


        cluster: {
          mode: false
        }
      }
    },
    mounted() {
      this.getTaskList();
      // this.init();
    },
    methods: {
      async query() {
        await this.pageTable.handleLoad();
      },
      handlerAdd() {
        this.edit.data = Object.assign({}, default_data);
        this.edit.readonly = false;
        this.edit.visible = true;
        this.$refs.form.resetFields();
      },
      async handlerOnce(uuid) {
        try {
          await this.confirm();
          this.pageTable.isLoading = true;
          await TaskMgrApi.once(uuid);
          await this.query();
        } finally {
          this.pageTable.isLoading = false;
        }
      },
      async handlerStart(uuid) {
        try {
          await this.confirm();
          this.pageTable.isLoading = true;
          await TaskMgrApi.start(uuid);
          await this.query();
        } finally {
          this.pageTable.isLoading = false;
        }
      },
      async handlerStop(uuid) {
        await this.confirm();
        await TaskMgrApi.stop(uuid);
        await this.query();
      },
      async handlerSave() {
        try {
          await this.$refs.form.validate();
          await this.confirm();
          this.edit.loading = true;
          let resp = await TaskMgrApi.save(this.edit.data);
          this.edit.data.uuid = resp.uuid;
          await this.query();
        } finally {
          this.edit.loading = false;
        }
      },
      async handlerDelete(uuid) {
        try {
          await this.confirm();
          this.pageTable.isLoading = true;
          await TaskMgrApi.delete(uuid);
          await this.query();
        } finally {
          this.pageTable.isLoading = false;
        }
      },
      async handlerView(uuid) {
        try {
          this.edit.data = {};
          this.edit.readonly = true;
          this.edit.loading = true;
          this.edit.visible = true;
          let resp = await TaskMgrApi.get(uuid);
          this.edit.data = resp.data;
        } finally {
          this.edit.loading = false;
        }
      },
      async handlerEdit(uuid) {
        try {
          this.edit.readonly = false;
          this.edit.loading = true;
          this.edit.visible = true;
          let resp = await TaskMgrApi.get(uuid);
          this.edit.data = resp.data;
        } finally {
          this.edit.loading = false;
        }
      },
      selectionChange(selection) {
        this.selection = selection;
      },
      async handlerMultiStart() {
        try {
          await this.confirm();
          this.pageTable.isLoading = true;
          let uuidList = this.selection.map(v => v.uuid);
          let resp = await TaskMgrApi.multiStart(uuidList);
          this.$message.success(`成功启动 ${resp.success} 个任务, 失败 ${resp.fail} 个`);
          this.$refs.table.clearSelection();
          await this.pageTable.handleLoad();
        } finally {
          this.pageTable.isLoading = false;
        }
      },
      async handlerMultiStop() {
        try {
          await this.confirm();
          this.pageTable.isLoading = true;
          let uuidList = this.selection.map(v => v.uuid);
          await TaskMgrApi.multiStop(uuidList);
          this.$refs.table.clearSelection();
          await this.pageTable.handleLoad();
        } finally {
          this.pageTable.isLoading = false;
        }
      },
      async getTaskList() {
        let resp = await TaskMgrApi.getTaskList();
        let _result = {};
        resp.data.forEach(v => {
          if (_result[v.type]) {
            _result[v.type].push(v);
          } else {
            _result[v.type] = [v];
          }
        })
        let result = [];
        for (let key in _result) {
          result.push({
            label: key,
            options: _result[key]
          });
        }

        this.taskList = result;
      },
      popoverShow() {
        this.currConfig = "{}";
        let className = this.edit.data.className;
        for (let i = 0; i < this.taskList.length; i++) {
          for (let j = 0; j < this.taskList[i].options.length; j++) {
            if (this.taskList[i].options[j].className === className) {
              this.currConfig = this.taskList[i].options[j].configTemplate;
              return;
            }
          }
        }
      },
      handleClickCopyClipboard() {
        let config = this.currConfig
        let aux = document.createElement("input");
        aux.setAttribute("value", JSON.stringify(JSON.parse(config), null, '  '));
        document.body.appendChild(aux);
        aux.select();
        document.execCommand("copy");
        document.body.removeChild(aux);
        this.$message.success("复制成功");
      },
      async handleClickCopyInput() {
        if (this.edit.data.config) {
          await this.confirm(null, '确认覆盖已存在的任务配置?');
        }
        let config = this.currConfig;
        this.edit.data.config = JSON.stringify(JSON.parse(config), null, '  ');
        this.$message.success("复制成功");
      }
    }
  }
</script>

<style scoped>

</style>