<template>
  <div>
    <div class="menu-title">
      模型管理
    </div>
    <div class="menu-content">
      <div>
        <el-form :inline="true" :model="qo" class="demo-form-inline">
          <el-form-item>
            <el-input v-model="qo.LIKES_name" placeholder="请输入模型名称"></el-input>
          </el-form-item>
          <el-form-item>
            <el-input v-model="qo.LIKES_name" placeholder="请输入算法名称"></el-input>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" icon="el-icon-search" @click="qo.pageNo=1;queryData()">搜 索</el-button>
          </el-form-item>
        </el-form>
      </div>
      <div style="margin: 0px 0 20px 0">
        <el-button type="primary" @click="createRow()">新增模型</el-button>
      </div>
      <div>
        <el-table :data="result.records" style="width: 100%" ref="table">
          <el-table-column type="index" label="行号" width="100"></el-table-column>
          <el-table-column prop="name" label="模型名称"></el-table-column>
          <el-table-column prop="algorithmId" label="算法名称" :formatter="algorithmIdFormatter"></el-table-column>
          <!-- <el-table-column prop="version" label="版本"></el-table-column> -->
          <el-table-column prop="status" label="训练状态" :formatter="statusFormatter"></el-table-column>
          <el-table-column prop="modifyTimeMillis" label="修改时间">
            <template slot-scope="scope">
              {{ scope.row.modifyTimeMillis | timeFilter }}
            </template>
          </el-table-column>
          <el-table-column prop="createTimeMillis" label="创建时间">
            <template slot-scope="scope">
              {{ scope.row.createTimeMillis | timeFilter }}
            </template>
          </el-table-column>
          <el-table-column label="操作" width="220">
            <template slot-scope="scope">
              <el-button @click.native.prevent="trainRow(scope.row)" type="text" size="small" v-if="scope.row.status != 8">
                训练
              </el-button>
              <el-button  type="text" size="small" v-if="scope.row.status == 8" style="color: #ccc;cursor: default" title="训练中">
                训练
              </el-button>
              <el-button @click.native.prevent="modifyRow(scope.row)" type="text" size="small" v-if="scope.row.status == 1">
                编辑
              </el-button>
              <el-button @click.native.prevent="removeRow(scope.row)" type="text" size="small" >
                删除
              </el-button>
              <br>
              <el-button @click.native.prevent="showLogDialog(scope.row)" type="text" size="small" v-if="scope.row.status == 8 || scope.row.status == 9">
                  日志
                </el-button>
                <el-button @click.native.prevent="updateStatus(scope.row, 'stop')" type="text" size="small" v-if="scope.row.status == 8">
                  停止
                </el-button>
                <!-- <el-button @click.native.prevent="updateStatus(scope.row, 'start')" type="text" size="small">
                  重启
                </el-button> -->
                <el-button @click.native.prevent="publishService(scope.row)" type="text" size="small" v-if="scope.row.status == 9">
                  发布服务
                </el-button>
                <el-button @click.native.prevent="testRow(scope.row)" type="text" size="small" v-if="scope.row.status == 9">
                  测试
                </el-button>
              <!-- <template v-show="scope.row.status == 0">
                
              </template> -->
            </template>
          </el-table-column>
        </el-table>
      </div>
      <div class="page-box">
        <el-pagination background
                       @current-change="handleCurrentChange"
                       :current-page="qo.pageNo"
                       :page-size="qo.pageSize"
                       layout="total, prev, pager, next"
                       :total="result.total">
        </el-pagination>
      </div>
    </div>
    <el-dialog
        :title="dialogName"
        :visible.sync="cmdDialogVisible"
        width="40%">
      <el-form ref="cmd" label-width="100px" :rules="rules" :model="cmd">
        <el-form-item label="模型名称" prop="name">
          <el-input v-model="cmd.name" placeholder="请输入模型名称"></el-input>
        </el-form-item>
        <el-form-item label="算法" prop="algorithmId">
          <el-select v-model="cmd.algorithmId" placeholder="请选择算法">
            <el-option :label="item.name" :value="item.id" :key="item.id" v-for="item in algorithmList"></el-option>
          </el-select>
        </el-form-item>
        <!--        <el-form-item label="数据集" prop="name">-->
        <!--          <el-select v-model="cmd.name" placeholder="请选择数据集">-->
        <!--            <el-option label="" value=""></el-option>-->
        <!--          </el-select>-->
        <!--        </el-form-item>-->
        <el-form-item label="描述">
          <el-input v-model="cmd.modelRemark" placeholder="请输入描述" type="textarea"></el-input>
        </el-form-item>

      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="cmdDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="submitModify">确 定</el-button>
      </span>
    </el-dialog>
    <el-dialog
        title="训练模型"
        :visible.sync="trainCmdDialogVisible"
        width="75%">
      <el-form ref="cmd" label-width="120px" :rules="rules" :model="cmd" v-loading="trainLoading" element-loading-text="程序启动中"  :inline="true">
        <div class="title-form-box">公共配置</div>
        <el-form-item :label="item.name" v-for="item in cmd.publicPropert" :key="item.key">
          <el-input v-model="item.value" :placeholder="'请输入' + item.name"></el-input>
        </el-form-item>
        <div class="title-form-box">私有配置</div>
        <el-form-item :label="item.name" v-for="item in cmd.privatePropert" :key="item.key">
          <el-input v-model="item.value" :placeholder="'请输入' + item.name" ></el-input>
        </el-form-item>
        <div class="title-form-box">资源选择</div>
        <el-form-item label="指定显卡" prop="gpuId">
          <el-select v-model="cmd.gpuId" placeholder="请选择显卡">
            <el-option :label="item.name" :value="item.id" :key="item.id" v-for="item in cmd.gpuInfoList"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="数据集" prop="dataSetId1">
          <el-select v-model="cmd.dataSetId1" placeholder="请选择数据集">
            <el-option :label="item.name" :value="item.id" :key="item.id" v-for="item in dataSetList"></el-option>
          </el-select>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="trainCmdDialogVisible = false">取 消</el-button>
        <el-button type="primary" :disabled="trainLoading" @click="submitTrain">确 定</el-button>
      </span>
    </el-dialog>

    <el-dialog
        title="发布服务"
        :visible.sync="serverCmdDialogVisible"
        width="75%">
      <el-form ref="cmd" label-width="120px" :rules="rules" :model="cmd">
        <el-form-item :label="item.name" v-for="item in cmd.privatePropert" :key="item.key">
          <el-input v-model="item.value" :placeholder="'请输入' + item.name" ></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="serverCmdDialogVisible = false">取 消</el-button>
        <el-button type="primary"  @click="submitPublishService">确 定</el-button>
      </span>
    </el-dialog>

    <el-dialog
        title="测试"
        :visible.sync="testCmdDialogVisible"
        destroy-on-close
        @close="handleTestDialogClose"
        width="40%">
      <el-form ref="cmd" label-width="100px" :rules="rules" :model="cmd" v-loading="testLoading">
        <el-form-item label="测试类型" prop="testType">
          <el-select v-model="cmd.testType" placeholder="请选择测试类型">
            <el-option label="单文本测试" value="text"></el-option>
            <el-option label="数据集测试" value="database"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="单文本测试" prop="text" v-if="cmd.testType == 'text'">
          <el-input v-model="cmd.text" placeholder="请输入所要测试的单文本"></el-input>
        </el-form-item>
        <el-form-item label="数据集测试" prop="dataSetId" v-if="cmd.testType == 'database'">
          <el-select v-model="cmd.dataSetId" placeholder="请选择数据集">
            <el-option :label="item.name" :value="item.id" :key="item.id" v-for="item in dataSetList"></el-option>
          </el-select>
        </el-form-item>
        <div class="log-title-box">服务日志</div>
        <log ref="log-item2" v-if="testSuccess"></log>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="testCmdDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="submitTest" :disabled="testLoading">开始测试</el-button>
      </span>
    </el-dialog>
    <el-dialog
        title="日志"
        :visible.sync="logDialogVisible"
        destroy-on-close
        @close="handleLogDialogClose"
        width="60%">
      <log ref="log-item"></log>
    </el-dialog>
  </div>
</template>

<script>
import request from '@/utils/request2';
import request1, {getBaseUrl} from '@/utils/request';
import log from '@/components/log/index';

var _this;
export default {
  name: "modelManage",
  components: {
    log
  },
  data() {
    return {
      qo: {
        pageNo: 1,
        pageSize: 10,
        LIKES_name: '',
      },
      result: {
        records: [],
        total: 0
      },
      algorithmList: [],
      dialogName: '编辑',
      cmdDialogVisible: false,
      trainCmdDialogVisible: false,
      serverCmdDialogVisible: false,
      cmd: {
        dataSetId: '',
        dataSetId1: ''
      },
      testSuccess: false,
      testLoading: false,
      rules: {
        name: [
          {required: true, message: '请输入模型名称'}
        ],
        algorithmId: [
          {required: true, message: '请选择算法'}
        ],
        gpuId: [
          {required: true, message: '请选择显卡'}
        ],
        testType: [
          {required: true, message: '请选择测试类型'}
        ],
        text: [
          {required: true, message: '请输入所要测试的单文本'}
        ],
        dataSetId: [
          {required: true, message: '请选择数据集'}
        ],
        dataSetId1: [
          {required: true, message: '请选择数据集'}
        ],
      },
      testCmdDialogVisible: false,
      dataSetList: [],
      logDialogVisible: false,
      statusList: {
        1: '保存状态',
        2: '开始',
        3: '运行中',
        4: '等待中',
        5: '结束',
        6: '发布失败',
        7: '取消',
        8: '训练中',
        9: '训练完成'
      },
      trainLoading: false,
      modelId: ''
    }
  },
  mounted() {
    _this = this;
    _this.queryData();
    _this.queryAlgorithmList();
    _this.queryDataSetList();
  },
  filters: {
    timeFilter(val) {
      if (val > 0) {
        let dt = new Date(val);
        let year = dt.getFullYear();
        let month = dt.getMonth() + 1;
        let date = dt.getDate();
        let hour = dt.getHours();
        let minute = dt.getMinutes();
        let second = dt.getSeconds();
        return `${year}-${month}-${date} ${hour}:${minute}:${second}`;
      } else {
        return "-";
      }
    }
  },
  methods: {
    algorithmIdFormatter(row) {
        let index = _this.algorithmList.findIndex(dataSet => {
          return row.algorithmId == dataSet.id;
        });
        return index >= 0 ? _this.algorithmList[index].name : '-';
    },
    statusFormatter(row) {
        return _this.statusList[row.status] || '-';
    },
    queryDataSetList() {
      request1({
        url: '/remark_task/query_list',
        method: 'post',
        data: {}
      }).then(res => {
        _this.dataSetList = res.data;
      });
    },
    showLogDialog(row) {
      _this.logDialogVisible = true;
      _this.$nextTick(() => {
        _this.$refs['log-item'].init({modelId: row.id, type: 'log_train'});
      });
    },
    handleLogDialogClose() {
      _this.$refs['log-item'].close();
    },
    handleTestDialogClose() {
      _this.$refs['log-item2'].close();
    },
    queryAlgorithmList() {
      request({
        url: '/algorithm/list',
        method: 'post',
        data: {pageNo: 1, pageSize: 1000}
      }).then(res => {
        _this.algorithmList = res.list;
      });
    },
    queryData() {
      request({
        url: '/model/list',
        method: 'post',
        data: _this.qo
      }).then(res => {
        _this.result.records = res.list;
        _this.result.total = res.total;
      });
    },
    handleCurrentChange(val) {
      _this.qo.pageNo = val;
      _this.queryData();
    },
    removeRow(item) {
      _this.$confirm('此操作将永久删除记录, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        request({
          url: '/model/remove',
          method: 'post',
          data: {
            id: item.id,
          }
        }).then(res => {
          _this.$message.success("删除成功");
          _this.queryData();
        });
      }).catch(() => {
      });
    },
    createRow() {
      _this.cmdDialogVisible = true;
      _this.$nextTick(() => {
        _this.dialogName = "新增";
        _this.cmd = {
          name: '',
          algorithmId: '',
          modelRemark: ''
        };
        _this.$refs.cmd.resetFields();
      });
    },
    trainRow(item) {
      let id = item.id;
      request({
        url: `/model/editTrainParameter/${id}`,
        method: 'post',
      }).then(res => {
        _this.cmd = res.data;
        _this.cmd.dataSetId = "";
        _this.trainLoading = false;
        _this.trainCmdDialogVisible = true;
      });

    },
    testRow(item) {
      _this.testSuccess = false;
      _this.testCmdDialogVisible = true;
      _this.$nextTick(() => {
        _this.cmd = {
          testType: '',
          text: '',
          dataSetId: '',
          modelId: item.id
        };
        _this.$refs.cmd.resetFields();
      });
    },
    modifyRow(item) {
      _this.cmdDialogVisible = true;
      _this.$nextTick(() => {
        _this.dialogName = "编辑";
        _this.cmd = JSON.parse(JSON.stringify(item));
        _this.cmd.modifyTimeMillis = null;
        _this.$refs.cmd.resetFields();
      });
    },
    submitModify() {
      this.$refs.cmd.validate((valid) => {
        if (valid) {
          request({
            url: '/model/save',
            method: 'post',
            data: _this.cmd
          }).then(res => {
            _this.$message.success("新增成功");
            _this.queryData();
            _this.cmdDialogVisible = false;
          });
        }
      });
    },
    submitTrain() { // 提交训练
      if(_this.trainLoading) {
        return
      }
      this.$refs.cmd.validate((valid) => {
        if (valid) {
          _this.trainLoading = true;
          _this.cmd.dataSetUrl = getBaseUrl() + "/es_remark_task/findbytaskidandtasktypeall/" + _this.cmd.dataSetId1 + "/";

          request({
            url: '/model/startTrain',
            method: 'post',
            data: _this.cmd
          }).then(res => {
            _this.$message.success("训练成功");
            _this.trainLoading = false;
            _this.queryData();
            _this.trainCmdDialogVisible = false;
          });
        }
      });
    },
    submitTest() { // 提交测试
      this.$refs.cmd.validate((valid) => {
        if (valid) {
          _this.testLoading = true;
          if (_this.cmd.testType == 'text') {
            request({
              url: '/model/singleTextTest',
              method: 'post',
              data: _this.cmd
            }).then(res => {
              _this.$message.success("测试成功");
              _this.testSuccess = true;
              _this.$nextTick(() => {
                _this.$refs['log-item2'].init({modelId: _this.cmd.modelId, type: 'test_single'});
                _this.testLoading = false;
              });
            });
          } else if (_this.cmd.testType == 'database') {
            let _cmd = JSON.parse(JSON.stringify(_this.cmd))
            _cmd.dataSetId = getBaseUrl() + "/es_remark_task/findbytaskidandtasktypeall/" + _cmd.dataSetId + "/";
            console.log(_cmd);
            request({
              url: '/model/dataSetTest',
              method: 'post',
              data: _cmd
            }).then(res => {
              _this.$message.success("测试成功");
              _this.testSuccess = true;
              _this.$nextTick(() => {
                _this.$refs['log-item2'].init({modelId: _this.cmd.modelId, type: 'log_test'});
                _this.testLoading = false;
              });
            });
          }
        }
      });
    },
    updateStatus(item, action) { // 修改状态，重启start，停止stop
      let text = action === 'start' ? '重启' : '停止';
      _this.$confirm(`此操作将执行${text}操作, 是否继续?`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        request({
          url: '/model/update/status',
          method: 'post',
          data: {
            modelId: item.id,
            action: action
          }
        }).then(res => {
          _this.$message.success(`${text}成功`);
          _this.queryData();
        });
      }).catch(() => {
      });
    },
    publishService(item) { // 发布服务
      let id = item.id;
      _this.modelId = id;
      request({
        url: `/model/getServerPropert/${id}`,
        method: 'post',
      }).then(res => {
        _this.cmd.privatePropert = res.data;
        _this.serverCmdDialogVisible = true;
      });
    },
    submitPublishService(item) { // 发布服务
      const loading = this.$loading({
          lock: true,
          text: '服务发布中',
          spinner: 'el-icon-loading',
          background: 'rgba(0, 0, 0, 0.7)'
        });
      request({
          url: '/model/publishService',
          method: 'post',
          data: {
            modelId: _this.modelId,
            serverPropert: _this.cmd.privatePropert
          }
        }).then(res => {
          _this.$message.success(`发布成功`);
          loading.close();
          _this.serverCmdDialogVisible = false;
          _this.queryData();
        });
    }
  }
}
</script>

<style lang="scss">
.log-title-box {
  font-size: 16px;
  font-weight: 600;
  margin-bottom: 10px;
}

.log-box {
  background-color: #c2c2c2;
  border-radius: 3px;
  min-height: 300px;
}

.title-form-box {
  font-weight: bold;
  font-size: 16px;
  padding-left: 5px;
  margin-bottom: 25px;
}
</style>
