<template>
  <div class="performanceAdd">
    <div class="header">
      <div class="name">
        <div class="name-wrap">测试名称</div>
        <el-input v-model="addForm.performanceName" placeholder="请输入名称" maxlength="255" show-word-limit></el-input>
      </div>
      <div class="save">
        <el-button type="primary" plain @click="handleWithSave">保存</el-button>
        <el-button type="primary" plain @click="handleWithSaveAndExecute">保存并执行</el-button>
        <el-button type="warning" plain @click="handleWithCancel">取消</el-button>
      </div>
      <div class="date">
        <div class="date-top">
          <i class="el-icon-date"></i>
          <span class="date-title">SCHEDULER</span>
          <el-switch v-model="switchOpen" @change="switchChange"></el-switch>
        </div>
        <div class="date-bottom">
          <span>下次执行时间</span>
        </div>
      </div>
    </div>
    <div class="tab">
      <el-tabs v-model="activeName" @tab-click="handleClick">
        <el-tab-pane label="场景配置" name="first">
          <div class="title">场景列表</div>
          <el-button style="margin-top: 10px; margin-bottom: 10px;" icon="el-icon-share"
            @click="handleClickLoad">引用接口自动化场景</el-button>
          <el-table :data="changeList">
            <el-table-column prop="name" label="场景名称" />
            <el-table-column prop="status" label="Enable/Disable">
              <template slot-scope="scope">
                <el-switch v-model="scope.row.status" active-value="1" inactive-value="0"></el-switch>
              </template>
            </el-table-column>
            <el-table-column prop="action" label="操作">
              <template slot-scope="scope">
                <el-button type="text" icon="el-icon-delete" style="color: red;"
                  @click="hadleClickDelete(scope.row)">删除</el-button>
              </template>
            </el-table-column>
          </el-table>
        </el-tab-pane>
        <el-tab-pane label="压力配置" name="second">
          <div class="pressure-header">
            <div class="title">速兑通接口</div>
            <div class="pressure-title">并发用户数{{ addForm.concurrentThreads }}，压测时长{{ addForm.pressureHour }}时{{
              addForm.pressureMinute }}分{{ addForm.pressureSecond }}秒</div>
          </div>
          <div class="pressure-wrap">
            <div class="pressure-warap-name">并发用户数</div>
            <el-input-number v-model="addForm.concurrentThreads" controls-position="right" :min="0"></el-input-number>
          </div>
          <div class="pressure-wrap">
            <div class="pressure-warap-name">取样器错误后</div>
            <el-select v-model="addForm.errorOperType" placeholder="请选择">
              <el-option key="1" label="继续" value="1"></el-option>
              <el-option key="2" label="开始下一个线程轮询" value="2"></el-option>
              <el-option key="3" label="停止线程" value="3"></el-option>
              <el-option key="4" label="停止测试" value="4"></el-option>
              <el-option key="5" label="立即停止测试" value="5"></el-option>
            </el-select>
          </div>
          <div class="pressure-wrap">
            <div class="pressure-warap-name">执行方式</div>
            <el-radio-group v-model="addForm.executeType">
              <el-radio-button :label="1">按持续时间</el-radio-button>
              <el-radio-button :label="2">按迭代次数</el-radio-button>
            </el-radio-group>
            <el-input-number v-if="addForm.executeType === 2" style="margin-left: 10px;" v-model="addForm.loopCount"
              controls-position="right" :min="0"></el-input-number>
          </div>
          <div class="pressure-wrap">
            <div class="pressure-warap-name">Ramp-Up</div>
            <el-input-number v-model="addForm.rampUpSeconds" controls-position="right" :min="0"></el-input-number>
            <div class="pressure-warap-name">秒</div>
          </div>
          <div class="pressure-wrap">
            <div class="pressure-warap-name">压测时长</div>
            <el-input-number v-model="addForm.pressureHour" controls-position="right" :min="0"></el-input-number>
            <div class="pressure-warap-name">时</div>
            <el-input-number v-model="addForm.pressureMinute" controls-position="right" :min="0"></el-input-number>
            <div class="pressure-warap-name">分</div>
            <el-input-number v-model="addForm.pressureSecond" controls-position="right" :min="0"></el-input-number>
            <div class="pressure-warap-name">秒</div>
          </div>
          <div class="pressure-wrap">
            <div class="pressure-warap-name">Rps开启</div>
            <el-switch v-model="addForm.rpsStatus" active-value="1" inactive-value="0"></el-switch>
            <div class="pressure-warap-name">Rps上限</div>
            <el-input-number v-model="addForm.rpsLimit" controls-position="right" :min="0"></el-input-number>
          </div>
        </el-tab-pane>
      </el-tabs>
    </div>
    <el-dialog title="场景列表" :visible.sync="dialogVisible" width="60%">
      <div class="search">
        <el-input v-model="searchScenen.name" style="width: 300px;" placeholder="根据ID/名称/标签 搜索"
          @blur="searchSecenList"></el-input>
      </div>
      <div class="table">
        <el-table ref="tableRef" :data="sceneList" @selection-change="handleSelectionChange">
          <el-table-column type="selection" width="55" align="center" />
          <el-table-column prop="id" width="100" label="ID" align="center" />
          <el-table-column prop="name" label="场景名称" align="center" />
          <el-table-column prop="remark" label="标签" align="center" />
          <el-table-column prop="createTime" label="修改时间" align="center" />
        </el-table>
        <div class="page">
          <el-pagination background @size-change="handleSizeChange" @current-change="handleCurrentChange"
            :page-size="searchScenen.pageSize" layout="total, sizes, prev, pager, next, jumper" :total="totalScene" />
        </div>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="handleWithSure">确 定</el-button>
      </span>
    </el-dialog>
    <el-dialog title="定时任务" :visible.sync="dialogVisibleTime" width="60%" :before-close="handleClose">
      <el-tabs v-model="activeTime">
        <el-tab-pane label="任务配置" name="first"></el-tab-pane>
        <div class="editTimeTitle">编辑定时任务</div>
        <div class="crontab-wrap">
          <div class="title">Crontab表达式</div>
          <el-input v-model="addForm.crontab" @input="updateExecutionTimes" placeholder="请输入crontab表达式" />
          <div class="title" style="margin-left: 50px;">定时任务开关</div>
          <el-switch v-model="addForm.crontabStatus" active-value="1" inactive-value="0"></el-switch>
        </div>
        <div class="near-time">
          <div class="title">最近5次运行时间</div>
          <div v-for="(item, index) in executionTimeList" :key="index">
            {{ item.time }}
          </div>
        </div>
      </el-tabs>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisibleTime = false, switchOpen = false">取 消</el-button>
        <el-button type="primary" @click="dialogVisibleTime = false">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import { addTest, addAndExecuteTest, getTestCaseList } from '../../../api/performance';

export default {
  name: "PerformanceAdd",
  data() {
    return {
      addForm: {
        performanceName: '', // 性能测试名称
        performanceTestCaseVOList: [], // 场景列表
        concurrentThreads: '0', // 并发用户数
        errorOperType: '', // 在取样器错误后要执行的动作，1：继续；2：开始下一个线程轮询；3：停止线程；4：停止测试；5：立即停止测试
        executeType: '', // 执行方式，1：按持续时间；2：按迭代次数
        rampUpSeconds: '0', // 多少秒内线程建立完成，默认0
        pressureHour: '0',  // 压测时长，时，默认0
        pressureMinute: '0', // 压测时长，分，默认0
        pressureSecond: '0', // 压测时长，秒，默认0
        rpsStatus: '0', //  rps状态：0关闭，1开启，默认0
        rpsLimit: '0', // 每分钟rps上限数，默认0
        crontab: '', // crontab表达式
        crontabStatus: '0', // 定时任务状态：0关闭，1开启，默认0
        loopCount: '0', // 迭代次数，默认0
      },
      activeName: 'first',
      sceneList: [], // 场景列表
      dialogVisible: false, // 场景列表
      searchScenen: {
        pageNum: 1,
        pageSize: 10,
        name: '', // 名称
      },
      totalScene: 0,
      searchScene: '',
      changeList: [],
      multipleSelection: [],
      switchOpen: false,
      dialogVisibleTime: false,
      activeTime: 'first',
      executionTimeList: [
        {
          time: "2025-02-18 10:00:00",
        },
        {
          time: "2025-02-19 10:00:00",
        },
        {
          time: "2025-02-20 10:00:00",
        },
        {
          time: "2025-02-21 10:00:00",
        },
        {
          time: "2025-02-22 10:00:00",
        },
      ],
      validation: false, // 校验
    }
  },
  mounted() {
    this.getTestCaseData()
  },
  methods: {
    // 校验
    validationForm() {
      if (this.addForm.performanceName === '' || this.addForm.performanceName === null) {
        this.$message({ message: '请输入测试名称', type: 'warning' })
        return
      }

      if (this.addForm.errorOperType === '' || this.addForm.errorOperType === null) {
        this.$message({ message: '请填写取样器错误后', type: 'warning' })
        return
      }

      if (this.addForm.executeType === '' || this.addForm.executeType === null) {
        this.$message({ message: '请选择执行方式', type: 'warning' })
        return
      }

      this.validation = true
    },
    // 保存
    handleWithSave() {
      this.validationForm()
      if (this.validation === false) { return }
      this.changeList.forEach(item => {
        var par = {
          testCaseId: item.id,
          status: item.status
        }
        this.addForm.performanceTestCaseVOList.push(par)
      })
      addTest(this.addForm).then(res => {
        if (res.code === 200) {
          this.$message({ message: '新增成功', type: 'success' })
          this.$tab.closeOpenPage({ path: "/performance/performance" });
        } else {
          this.$message({ message: '新增失败', type: 'error' })
        }
      })
    },
    // 保存并执行
    handleWithSaveAndExecute() {
      this.validationForm()
      if (this.validation === false) { return }
      if (this.addForm.crontab === '' || this.addForm.crontab === null) {
        this.$message({ message: '请输入Crontab表达式', type: 'warning' })
        return
      }
      // 需要校验crontab表达式
      addAndExecuteTest(this.addForm).then(res => {
        if (res.code === 200) {
          this.$message({ message: '新增成功', type: 'success' })
          this.$tab.closeOpenPage({ path: "/performance/performance" });
        } else {
          this.$message({ message: '新增失败', type: 'error' })
        }
      })
    },
    // 取消
    handleWithCancel() {
      this.$tab.closeOpenPage({ path: "/performance/performance" });
    },
    handleClick() { },
    // 加载jmx文件
    handleClickLoad() {
      this.dialogVisible = true
    },
    // 删除
    hadleClickDelete(val) {
      this.changeList = this.changeList.filter(item => item !== val);
      this.multipleSelection = this.multipleSelection.filter(item => item !== val);
      this.sceneList.forEach(row => {
        if (this.multipleSelection.includes(row)) {
          this.$refs.tableRef.toggleRowSelection(row, true);
        } else {
          this.$refs.tableRef.toggleRowSelection(row, false);
        }
      })
    },
    // netWorking
    getTestCaseData() {
      getTestCaseList(this.searchScenen).then(res => {
        if (res.code === 200) {
          this.sceneList = res.rows
          this.totalScene = res.total
        }
      })
    },
    searchSecenList() {
      this.getTestCaseData()
    },
    // 分页
    handleSizeChange(val) {
      this.searchScenen.pageSize = val
      this.getTestCaseData()
    },
    handleCurrentChange(val) {
      this.searchScenen.pageNum = val
      this.getTestCaseData()
    },
    handleSelectionChange(val) {
      this.multipleSelection = val;
    },
    handleWithSure() {
      this.changeList = this.multipleSelection
      this.changeList.forEach(item => {
        item.status = '1'
      })
      this.dialogVisible = false
    },
    switchChange(val) {
      this.dialogVisibleTime = val
    },
    handleClose() {
      this.dialogVisibleTime = false
      this.switchOpen = false
    },
    // 根据crontab表达式更新执行时间
    updateExecutionTimes() {
      const crontab = this.addForm.crontab.trim();
      if (!crontab) {
        this.executionTimeList = [];
        return;
      }

      try {
        // 解析crontab表达式
        const interval = cronParser.parseExpression(crontab);
        const times = [];

        // 获取最近三次执行时间
        for (let i = 0; i < 3; i++) {
          const nextTime = interval.next().toDate(); // 获取 Date 对象
          const formattedTime = this.formatDate(nextTime); // 格式化时间
          times.push({ time: formattedTime });
        }

        this.executionTimeList = times;
      } catch (error) {
        console.error('无效的crontab表达式:', error);
        this.executionTimeList = [{ time: '无效的crontab表达式' }];
      }
    },
  }

}

</script>


<style scoped lang="scss">
.performanceAdd {
  padding: 20px;

  .header {
    display: flex;
    justify-content: space-between;

    .name {
      display: flex;
      width: 300px;
      align-items: center;

      .name-wrap {
        width: 80px;
        font-size: 14px;
      }
    }
  }

  .tab {
    margin-top: 20px;

    .title {
      font-size: 14px;
      font-weight: 600;
    }
  }

  .search {
    display: flex;
    justify-content: flex-end;
    margin-bottom: 10px;
  }

  .page {
    padding: 10px;
    display: flex;
    justify-content: flex-end;
  }

  .pressure-header {
    display: flex;
    align-items: center;
    margin-bottom: 10px;

    .pressure-title {
      margin-left: 20px;
      font-size: 12px;
      font-weight: 500;
    }
  }

  .pressure-wrap {
    display: flex;
    padding: 10px;
    align-items: center;

    .pressure-warap-name {
      font-size: 14px;
      font-weight: 400;
      margin: 0px 10px;
    }
  }

  .date {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;

    .date-top {
      display: flex;

      .date-title {
        font-size: 14px;
        font-weight: 500;
        margin: 0px 10px;
      }
    }

    .date-bottom {
      display: flex;
      margin: 10px;
    }

  }

  .editTimeTitle {
    font-size: 14px;
    font-weight: 500;
    margin-bottom: 10px;
  }

  .crontab-wrap {
    display: flex;
    align-items: center;

    .title {
      font-size: 14px;
      width: 150px;
      margin-right: 20px;
    }
  }

  .near-time {
    margin-top: 20px;
    padding: 20px 10px;
    border: solid #dcdfe6 1px;
  }
}
</style>
