<template>
  <div>
    <el-row>
      <el-col>
        <el-button @click="add()" type="success" style="margin-left: 20px;" size="mini"><i
            class="el-icon-plus"></i>
          新增
        </el-button>
        <div style="text-align: right;float:right;">
          <el-input v-model="queryName" size="mini" autocomplete="off" placeholder="规则名称"
                    style="width:150px;margin-left:20px"
          ></el-input>
          <el-select
              v-model="queryCrawlMethod"
              placeholder="采集模式"
              style="width:150px;margin-left:20px"
              size="mini">
            <el-option
                v-for="option in crawlMethodOptions"
                :key="option.value"
                :label="option.label"
                :value="option.value">
            </el-option>
          </el-select>
          <el-select
              v-model="queryUseSelenium"
              placeholder="渲染模式"
              style="width:150px;margin-left:20px"
              size="mini">
            <el-option
                v-for="option in useSeleniumOptions"
                :key="option.value"
                :label="option.label"
                :value="option.value">
            </el-option>
          </el-select>
          <el-button @click="query" type="primary" size="mini" style="margin-left:20px"><i
              class="el-icon-search"></i> 查询
          </el-button>
          <el-button @click="resetSearch" type="info" size="mini" style="margin-left:20px"><i
              class="el-icon-refresh"></i> 重置
          </el-button>
        </div>
        <myTable :metaData="metadata" :tableData="tableData" :isLoading="isLoading"
                 @selection-change="handleSelectionChange">
          <template #default="{ index }">
            <el-button-group>
              <el-button size="small" icon="fa fa-edit" @click="edit(tableData[index])"></el-button>
              <el-button size="small" icon="fa fa-trash" @click="deleteOne(tableData[index].id)"></el-button>
            </el-button-group>
          </template>
        </myTable>
        <el-pagination
            style="padding: 15px"
            background
            layout="total, prev, pager, next, jumper"
            :total="total"
            :current-page="pageIndex"
            @current-change="onPageChange"
        ></el-pagination>
      </el-col>
    </el-row>
    <parserDialog :metaData="metadata" :form="form" :dialogTitle="dialogTitle" :dialogVisible="dialogVisible"
                  :cronList="cronList" :depthList="depthList" :closeDialog="closeDialog" :submit="submit"
    ></parserDialog>
  </div>
</template>

<script>
import {mapActions, mapMutations, mapState} from 'vuex'
import Vue from 'vue'
import {
  Button,
  Card,
  Checkbox,
  Col,
  Input,
  InputNumber,
  Message,
  MessageBox,
  Option,
  Pagination,
  Radio,
  Select
} from 'element-ui'
import myTable from "../components/CustomTable";
import parserDialog from "./ParserDialog";
import rulesParserApi from "../../js/api/rulesParserApi";
import metaDictApi from "../../js/api/metaDictApi";

Vue.use(Card);
Vue.use(Button);
Vue.use(Input);
Vue.use(InputNumber);
Vue.use(Checkbox);
Vue.use(Col);
Vue.use(Radio);
Vue.use(Select);
Vue.use(Option);
Vue.use(Pagination);

export default {
  name: "ParserTab",
  components: {
    'myTable': myTable,
    'parserDialog': parserDialog
  },
  data() {
    return {
      modify: false,
      pageIndex: 1,
      queryName: "",
      queryCrawlMethod: "",
      queryUseSelenium: "",
      useSeleniumOptions: [],
      crawlMethodOptions: [],
      multipleSelection: [],
      dialogVisible: false,
      dialogTitle: "",
      form: {
        parserName: "",
        startUrl: "",
        allowDomain: "",
        crawlMethod: 0,
        detailPageReg: "",
        itemPropMap: [],
        timeZone: 8,
        depth: 2,
        cron: "0 0 0/6 * * ?",
        lengthLimit: "",
        useSelenium: 0,
        useProxy: 0,
      },
      formLabelWidth: "100px",
      formInputWidth: "200px",
      saveLoading: false,
      deleteLoading: false,
      depthList: [
        {label: '只采起始站点', value: 0},
        {label: '1', value: 1},
        {label: '2', value: 2},
        {label: '3', value: 3},
        {label: '4', value: 4},
        {label: '5', value: 5}
      ],
      cronList: [],
    }
  },
  methods: {
    handleSelectionChange(val) {
      this.multipleSelection = val;
    },
    setDataBody() {
      let dataBody = {}
      if (this.queryCrawlMethod.length > 0) {
        dataBody.crawlMethod = this.queryCrawlMethod;
      }
      if (this.queryUseSelenium.length > 0) {
        dataBody.useSelenium = this.queryUseSelenium;
      }
      if (this.queryName.length > 0) {
        dataBody.parserName = this.queryName;
      }
      return dataBody;
    },
    onPageChange(index) {
      this.pageIndex = index;
      let dataBody = this.setDataBody()
      this.queryPageable({
        index: index - 1,
        size: 10,
        data: dataBody
      });
    },
    add() {
      this.resetFormData();
      if (this.form.itemPropMap.length <= 0) {
        this.addFieldRule()
      }
      this.dialogTitle = "添加记录";
      this.saveLoading = false;
      this.dialogVisible = true;
    },
    edit(data) {
      this.dialogTitle = "修改记录";
      this.form = JSON.parse(JSON.stringify(data));
      this.form.itemPropMap = JSON.parse(this.form.itemPropMap.replaceAll("\\", "\\\\"));
      let mapping = []
      for (let propField in this.form.itemPropMap) {
        mapping.push({field: propField, value: this.form.itemPropMap[propField]})
      }
      this.form.itemPropMap = mapping;
      // console.log(this.form);
      this.saveLoading = false;
      this.dialogVisible = true;
    },
    deleteOne(id) {
      MessageBox.confirm("是否删除？", "提示", {
        confirmButtonText: "确认",
        cancelButtonText: "取消",
        type: "warning",
      })
          .then(() => {
            rulesParserApi.deleteByIds({id: id}, (response) => {
              if (response.data.code === 200) {
                Message.success("删除成功")
                this.refreshPage()
              } else {
                this.refreshPage()
              }
            })
          })
          .catch(() => {
          });
    },
    closeDialog() {
      this.saveLoading = false;
      this.dialogVisible = false;
      this.refreshPage();
    },
    submit() {
      this.saveLoading = true;
      let dataBody = {}
      for (let formField in this.form) {
        if (formField !== 'itemPropMap') {
          dataBody[formField] = this.form[formField];
        } else {
          let propMap = {}
          const propMapList = this.form[formField];
          for (let i = 0; i < propMapList.length; ++i) {
            propMap[propMapList[i].field] = propMapList[i].value
          }
          dataBody[formField] = JSON.stringify(propMap).replaceAll("\\\\", "\\")
          // 注意，这里必须在 stringfy 之后二次将双反斜杠转换成单个，以适应日期正则表达式的情况
        }
      }
      if (this.form.id === undefined) {
        rulesParserApi.add(dataBody, (response) => {
          if (response.data.code === 200) {
            this.closeDialog();
            Message.success("添加成功")
          } else {
            this.closeDialog();
            Message.error("添加失败")
          }
        })
      } else {
        rulesParserApi.update(dataBody, (response) => {
          if (response.data.code === 200) {
            this.closeDialog();
            Message.success("更新成功")
          } else {
            this.closeDialog();
            Message.error("更新失败")
          }
        })
      }
      this.saveLoading = false;
    },
    query() {
      this.pageIndex = 1;
      let dataBody = this.setDataBody();
      this.queryPageable({
        index: 0,
        size: 10,
        data: dataBody,
      });
    },
    buildDictTree(data, columnString) {
      let siteOptions = []
      let nodeList = []
      data.forEach(e => {
        if (e.columnName === columnString)
          nodeList.push({
            value: e.dictCode,
            label: e.dictValue,
            children: undefined,
            parentDictCode: e.parentDictCode
          });
      })
      nodeList.forEach(e1 => {
        if (e1.parentDictCode !== undefined) {
          nodeList.forEach(e2 => {
            if (e1.parentDictCode === e2.value) {
              if (e2.children === undefined) {
                e2.children = []
              }
              e2.children.push(e1);
            }
          })
        } else {
          siteOptions.push(e1);
        }
      })
      return siteOptions;
    },
    resetSearch() {
      this.pageIndex = 1;
      this.queryUseSelenium = ""
      this.queryCrawlMethod = ""
      this.queryName = "";
      this.queryPageable({
        index: 0,
        size: 10,
        data: {},
      });
    },
    resetFormData() {
      this.form = {
        parserName: "",
        startUrl: "",
        allowDomain: "",
        crawlMethod: 0,
        detailPageReg: "",
        itemPropMap: [],
        timeZone: 8,
        depth: 2,
        cron: "0 0 0/6 * * ?",
        lengthLimit: "",
        useSelenium: 0,
        useProxy: 0,
      }
    },
    refreshPage() {
      this.saveLoading = false;
      let dataBody = this.setDataBody();
      this.queryPageable({
        index: this.pageIndex - 1,
        size: 10,
        data: dataBody,
      });
    },
    addFieldRule() {
      this.form.itemPropMap.push({value: '', field: 'es_urltitle'});
      this.form.itemPropMap.push({value: '', field: 'es_urlcontent'});
      this.form.itemPropMap.push({value: '', field: 'es_urltime'});
      this.form.itemPropMap.push({value: '', field: 'es_lasttime'});
    },
    ...
        mapMutations({}),
    ...
        mapActions({
          queryPageable: 'rulesParser/queryPageable',
        })
  }
  ,
  computed: {
    metadata: function () {
      const temp = [];
      this.$store.state.metadata.metadata.forEach((element) => {
        if (element.tableName === "rules_parser") {
          let tempElement = {...element};
          tempElement.minWidth = tempElement.columnWidth + "%";
          tempElement.columnWidth = 0;
          temp.push(tempElement);
        }
      });
      return temp;
    },
    esFields: function () {
      let temp = [];
      this.$store.state.metadata.metadata.forEach(element => {
        if (element.tableName === 'es_public_info') {
          temp.push(element);
        }
      });
      return temp;
    },
    ...
        mapState({
          tableData: (state) => state.rulesParser.table,
          total: (state) => state.rulesParser.count,
          isLoading: (state) => state.rulesParser.isLoading
        })
  },
  mounted() {
    this.refreshPage();
    metaDictApi.queryByTableName('rules_parser', (response) => {
      if (response.data.code === 200) {
        this.useSeleniumOptions = this.buildDictTree(response.data.content, 'useSelenium');
        this.crawlMethodOptions = this.buildDictTree(response.data.content, 'crawlMethod');
        this.cronList = this.buildDictTree(response.data.content, 'cronList');
      }
    })
  }
}
</script>

<style scoped>
.height {
  margin-top: 20px;
}

.table {
  margin-top: 20px;
}

.dialogForm {
  display: flex;
  justify-content: center;
}

.demo-form {
  width: 400px;
}

.box-card .text_label {
  text-align: right;
  vertical-align: middle;
  float: left;
  font-size: 14px;
  color: #606266;
  padding: 0 12px 0 0;
  box-sizing: border-box;
  width: 100%;
  line-height: 28px;
}

.box-card {
  background-color: #f8f8f8;
  margin-bottom: 10px;
  padding-bottom: 15px;
}

.box-card .title {
  text-align: center;
  font-size: 18px;
  padding: 10px;
  color: #666;
}

.box-card .dot {
  display: inline-block;
  vertical-align: middle;
  width: 6px;
  height: 6px;
  margin: 0 15px;
  background-color: #0080e5;
}

.el-input__inner {
  height: 28px !important;
  line-height: 28px !important;
}

.card-item {
  height: 41px;
  margin-top: 10px;
}

.el-cascader--mini {
  width: 100%;
}

.logintype_content {
  margin: 5px;
  border: 1px solid rgb(221, 221, 221);
  background-color: rgb(242, 242, 242);
  padding: 10px 10px 0 10px;
}

.el-page-header, .el-page-header__content {
  color: #666 !important;
}

.parse-button-icon {
  text-align: center;
  color: #409EFF;
}

.el-radio {
  margin-top: 5px;
}

.el-button:focus, .el-button:hover {
  margin-right: 0px;
}

.el-pagination {
  display: flex;
  justify-content: center;
}

</style>