<template>
  <!-- 页面样式编写 -->
  <div class="wrap">
    <!-- 搜索框样式 -->
    <div class="searchBox">
      <div class="searhinput">
        <baseNewForm
          v-loading="searchLoading"
          :spanNumber="12"
          refName="searchForm"
          :formRow="searchformRow"
          :formRule="false"
          :ruleForm="searchForm"
          :newFlag="true"
          :isFunBtn="false"
        ></baseNewForm>
      </div>
      <div class="searchbtn">
        <el-button type="primary" @click="searchBtnHandle">查询</el-button>
        <el-button @click="resizeBtnHandle">重置</el-button>
      </div>
    </div>
    <!-- 列表 -->
    <div class="tablebox">
      <div class="tablebtn">
        <el-button type="primary" @click="goAddHandle">新建API</el-button>
      </div>
      <div class="tablecontent">
        <baseNewTable
          ref="mainTable"
          :tableData="mainTableData"
          :tableColumn="mainTableColumn"
          :funData="mainFunData"
          :funWidth="funWidth"
          :showIndex="true"
          :tabLoading="mainTabLoading"
          @onFunc="tableButtonHandle"
          @view="viewHandle"
          :border="false"
          :tableHeight="'60vh'"
        ></baseNewTable>
      </div>
    </div>
    <!-- 分页 -->
    <div class="page">
      <basePage
        :pageModel="pageModel"
        @update:pageModel="currentChangeHandle"
      ></basePage>
    </div>
    <!-- 调试界面样式 -->
    <baseRightDialog
      :dialogVisible="rightDialog"
      title="API调试"
      @handleClose="dialoghandleClose"
      @handleConfirmClick="debugGoHandle"
      :submitShow="false"
    >
      <div>
        <div
          class="rightdalog"
          style="width: 100%; padding: 20px"
          v-if="rightDialog"
        >
          <template v-if="debugInfo.needLogin == '是'">
            <div class="debugchunk">
              <div class="title" style="margin: 20px 0">
                <h1>认证接口</h1>
              </div>
              <div class="code-json-editor">
                <vue-json-editor
                  class="editor"
                  v-model="authInfo"
                  :showBtns="false"
                  :mode="'code'"
                  @json-change="onAuthJsonChange"
                  @json-save="onAuthJsonSave"
                  @has-error="onAuthError"
                />
              </div>
              <div class="btn">
                <el-button
                  type="primary"
                  :loading="authDebugGoLoading"
                  @click="authDebugGoHandle"
                  style="margin: 20px 0"
                  >认证调试</el-button
                >
              </div>
              <div class="title" style="margin: 20px 0">
                <h1>认证结果展示</h1>
              </div>
              <div
                class="result"
                style="margin-top: 30px"
                v-loading="authResultLoading"
                v-if="Object.keys(authJsonData).length"
              >
                <json-view :data="authJsonData" />
              </div>
            </div>
          </template>
          <template>
            <div class="debugchunk">
              <div class="title" style="margin: 20px 0">
                <h1>测试数据设置</h1>
              </div>
              <div class="code-json-editor">
                <vue-json-editor
                  v-model="resultInfo"
                  :showBtns="false"
                  :mode="'code'"
                  @json-change="onJsonChange"
                  @json-save="onJsonSave"
                  @has-error="onError"
                  class="json-editor"
                />
              </div>
              <div class="btn">
                <el-button
                  type="primary"
                  :loading="debugGoLoading"
                  @click="debugGoHandle"
                  style="margin: 20px 0"
                  >开始调试</el-button
                >
              </div>
              <h1>测试结果展示</h1>
              <div
                class="result"
                style="margin-top: 30px"
                v-loading="resultLoading"
                v-if="Object.keys(jsonData).length"
              >
                <json-view :data="jsonData" />
              </div>
            </div>
          </template>
        </div>
      </div>
    </baseRightDialog>
  </div>
</template>

<script>
// 引入模块部份
import { deepClone } from "@/utils/index.js";
import jsonView from "vue-json-views";
import vueJsonEditor from "vue-json-editor";
import baseRightDialog from "./compoments/baseRightDialog";
import baseNewForm from "./compoments/baseNewForm.vue";
import baseNewTable from "./compoments/baseTable.vue";
import basePage from "./compoments/basePage.vue";
import { getApiModuleApi, getApiResultApi } from "@/api/apiChunks/index.js";
import axios from "axios";
export default {
  name: "ApiAdmin",
  data() {
    //数据源
    return {
      // 调试loading
      debugGoLoading: false,
      authDebugGoLoading: false,
      authResultLoading: false,
      resultLoading: false,
      // json数据
      authJsonData: {},
      jsonData: {},
      // json是否验证通过
      hasJsonFlag: true, // json是否验证通过
      authJsonFlag: true,
      //json数据
      resultInfo: {},
      authInfo: {},
      // 侧边栏是否开启
      rightDialog: false,
      // 搜索框loading
      searchLoading: false,
      // 搜索框输入数据
      searchForm: {},
      // 搜索框模版
      searchformRow: [
        {
          elCol: [
            {
              type: "input",
              title: "API名称",
              id: "apiCode",
            },
            {
              type: "select",
              title: "选择系统",
              id: "appId",
              options: [],
            },
          ],
        },
      ],
      // mainloading
      mainTabLoading: false,
      // 表格数据
      mainTableData: [],
      // 表格框架
      mainTableColumn: [
        {
          id: "apiCode",
          title: "API名称",
        },
        {
          id: "appName",
          title: "归属系统",
        },
        {
          id: "createUser",
          title: "创建人",
        },
        {
          id: "createTime",
          title: "创建时间",
        },
      ],
      // 表格操作按钮
      mainFunData: [
        {
          type: "edit",
          text: "编辑",
          color: "#5a9cf8",
        },
        {
          type: "debug",
          text: "调试",
          color: "#5a9cf8",
        },
        {
          type: "dele",
          text: "删除",
          color: "#e47470",
        },
      ],
      // 页码
      pageModel: {
        pageIndex: 1,
        total: 2,
        limit: 10,
      },
      // dialog表单数据
      // dialoghForm: {
      //   source: 1,
      //   testenv: 1,
      // },
      // dialog表单模型
      // dialogformRow: [
      //   {
      //     elCol: [
      //       {
      //         type: "radio",
      //         title: "调用来源",
      //         id: "source",
      //         options: [
      //           {
      //             label: "APP",
      //             id: 1,
      //           },
      //         ],
      //       },
      //       {},
      //     ],
      //   },
      //   {
      //     elCol: [
      //       {
      //         type: "radio",
      //         title: "选择测试环境",
      //         id: "testenv",
      //         options: [
      //           {
      //             label: "联调",
      //             id: 1,
      //           },
      //           {
      //             label: "生产",
      //             id: 2,
      //           },
      //         ],
      //       },
      //     ],
      //   },
      // ],
      // 点击调试后api接口信息
      debugInfo: {},
      authDebugInfo: {},
    };
  },
  methods: {
    // 删除行
    async deleTableHandle(id) {
      const res = await getApiModuleApi(
        {
          tl: "appApiService",
          as: "appApi",
          dj: "deleteEntity",
        },
        { id }
      );
      if (res.status == 200) {
        if (
          this.pageModel.pageIndex * this.pageModel.limit >=
          this.pageModel.total - 1 + this.pageModel.limit
        ) {
          this.pageModel.pageIndex--;
        }
        this.$nextTick(() => {
          this.getApiModuleHandle(this.searchForm);
        });
      }
    },
    // 初始化搜索框的下拉
    async initSysSelect() {
      const res = await getApiModuleApi({
        tl: "sysAppService",
        as: "app",
        dj: "queryList",
      });
      if (res.status == 200) {
        res.attribute.forEach((item) => {
          this.searchformRow[0].elCol[1].options.push({
            id: item.id,
            label: item.name,
          });
        });
      }
    },
    // 获取api模块
    async getApiModuleHandle(obj = {}) {
      this.mainTabLoading = true;
      const res = await getApiModuleApi(
        {
          tl: "appApiService",
          as: "appApi",
          dj: "queryPage",
        },
        {
          pageNum: this.pageModel.pageIndex,
          pageSize: this.pageModel.limit,
          ...obj,
        }
      );
      if (res.status == 200) {
        if (
          this.pageModel.pageIndex * this.pageModel.limit >=
          this.pageModel.total - 1 + this.pageModel.limit
        ) {
          this.pageModel.pageIndex--;
        }
        this.pageModel.total = res.attribute.total;
        this.mainTableData = res.attribute.list;
        this.$nextTick(() => {
          this.$refs.mainTable.setTableKey();
        });
      }
      this.mainTabLoading = false;
    },
    // 实时保存
    onAuthJsonChange(value) {
      this.onAuthJsonSave(value);
    },
    onAuthJsonSave(value) {
      this.authInfo = value;
      this.authJsonFlag = true;
    },
    onAuthError(value) {
      this.authJsonFlag = false;
    },
    checkAuthJson() {
      if (this.authJsonFlag === false) {
        alert("json验证失败");
        return false;
      } else {
        return true;
      }
    },
    onJsonChange(value) {
      this.onJsonSave(value);
    },
    // json相关
    onJsonSave(value) {
      this.resultInfo = value;
      this.hasJsonFlag = true;
    },
    // json相关（不用管）
    onError(value) {
      this.hasJsonFlag = false;
    },
    // json相关（不用管）
    checkJson() {
      if (this.hasJsonFlag === false) {
        alert("json验证失败");
        return false;
      } else {
        return true;
      }
    },
    // 关闭dialog事件
    dialoghandleClose() {
      this.rightDialog = false;
      this.jsonData = {};
      this.authJsonData = {};
      this.resultInfo = {};
      this.authInfo = {};
    },
    // 搜索框按钮
    searchBtnHandle() {
      this.pageModel.pageIndex = 1;
      this.$nextTick(() => {
        this.getApiModuleHandle(this.searchForm);
      });
    },
    // 重置按钮
    resizeBtnHandle() {
      this.searchForm = {};
    },
    // 点击调试后接口信息获取以及二次加工
    async getDebugInfoHandle(id, json) {
      const res = await getApiModuleApi(
        {
          tl: "appApiService",
          as: "appApi",
          dj: "queryEntity",
        },
        { id }
      );
      if (res.status == 200) {
        // 将表格数据转json
        let queryObj = {};
        let headerObj = {};
        let bodyObj = {};
        let bodyOut = {};
        if (res.attribute.needLogin == 1) {
          this.getDebugInfoHandle(
            res.attribute.authenticationPort,
            this.authInfo,
            this.authDebugInfo
          ).then((val) => (this.authDebugInfo = val));
        }
        if (
          JSON.parse(res.attribute.headerIn) &&
          JSON.parse(res.attribute.headerIn).length
        ) {
          this.DebugDataHandle(headerObj, JSON.parse(res.attribute.headerIn));
          this.$set(json, "headers", deepClone(headerObj));
        } else {
          this.$set(json, "headers", {});
        }
        if (
          JSON.parse(res.attribute.queryIn).length &&
          JSON.parse(res.attribute.queryIn).length
        ) {
          this.DebugDataHandle(queryObj, JSON.parse(res.attribute.queryIn));
          this.$set(json, "query", deepClone(queryObj));
        } else {
          this.$set(json, "query", {});
        }
        if (
          JSON.parse(res.attribute.bodyIn).length &&
          JSON.parse(res.attribute.bodyIn).length
        ) {
          this.DebugDataHandle(bodyObj, JSON.parse(res.attribute.bodyIn));
          this.$set(json, "body", deepClone(bodyObj));
        } else {
          this.$set(json, "body", {});
        }
        // 数据字典处理
        let tempObj = { ...res.attribute };
        let obj = {
          needLogin: {
            1: "是",
            2: "否",
          },
          enableAccessEntry: {
            1: "APP",
            2: "H5",
          },
          requestCoding: {
            1: "UTF-8",
          },
          parameterPassingMode: {
            1: "query",
            2: "data",
          },
          requestMethod: {
            1: "POST",
            2: "GET",
          },
          serviceAccessProtocol: {
            1: "HTTP",
            2: "HTTPS",
          },
        };
        Object.keys(tempObj).forEach((item) => {
          if (obj[item]) {
            if (JSON.parse(tempObj[item]) instanceof Array) {
              let tempstr = "";
              JSON.parse(tempObj[item]).forEach((ele) => {
                tempstr += obj[item][ele] + "、";
              });
              tempObj[item] = tempstr.slice(0, -1);
            } else {
              tempObj[item] = obj[item][tempObj[item] * 1];
            }
          }
        });
        return tempObj;
      }
    },
    // 点击调试
    async debugGoHandle() {
      if (this.checkJson()) {
        this.debugGoLoading = true;
        this.resultLoading = true;
        let tempUrl =
          this.debugInfo.serviceAccessProtocol +
          "://" +
          this.debugInfo.destinationAddress;
        try {
          if (
            this.resultInfo.query &&
            Object.keys(this.resultInfo.query).length
          ) {
            tempUrl = tempUrl + "?";
            Object.keys(this.resultInfo.query).forEach((item) => {
              tempUrl += `${item}=${this.resultInfo.query[item]}&`;
            });
            tempUrl = tempUrl.slice(0, -1);
          }
          const res = await getApiResultApi({
            method: this.debugInfo.requestMethod,
            url: tempUrl,
            ...this.resultInfo,
          });
          if (res.status == 200) {
            this.jsonData = deepClone(JSON.parse(res.msg));
          }
        } catch (error) {
          this.$message({
            type: "warning",
            message: error,
          });
        }
        this.resultLoading = false;
        this.debugGoLoading = false;
      }
    },
    //点击认证调试
    async authDebugGoHandle() {
      this.authDebugGoLoading = true;
      if (this.checkAuthJson()) {
        this.authResultLoading = true;
        let tempUrl =
          this.authDebugInfo.serviceAccessProtocol +
          "://" +
          this.authDebugInfo.destinationAddress;
        try {
          if (this.authInfo.query && Object.keys(this.authInfo.query).length) {
            tempUrl = tempUrl + "?";
            Object.keys(this.authInfo.query).forEach((item) => {
              tempUrl += `${item}=${this.authInfo.query[item]}&`;
            });
            tempUrl = tempUrl.slice(0, -1);
          }
          const res = await getApiResultApi({
            method: this.authDebugInfo.requestMethod,
            url: tempUrl,
            ...this.authInfo,
          });
          if (res.status == 200) {
            this.authJsonData = deepClone(JSON.parse(res.msg));
            this.authDataSearch();
          }
        } catch (error) {
          this.$message({
            type: "warning",
            message: error,
          });
        }
        this.authResultLoading = false;
      }
      this.authDebugGoLoading = false;
    },

    authDataSearch() {
      if (JSON.parse(this.debugInfo.headerIn)) {
        this.authDataHandle(
          this.resultInfo.headers,
          JSON.parse(this.debugInfo.headerIn)
        );
      }
      if (JSON.parse(this.debugInfo.bodyIn)) {
        this.authDataHandle(
          this.resultInfo.body,
          JSON.parse(this.debugInfo.bodyIn)
        );
      }
    },
    authDataHandle(obj, arr) {
      arr.forEach((item) => {
        if (item.parameterType === "authport") {
          obj[item.parameterName] = this.authDataReturn(item.example);
        }
        if (item.children && item.children.length) {
          this.authDataHandle(obj[item.parameterName], item.children);
        }
      });
    },
    authDataReturn(arr) {
      let temp = deepClone(this.authJsonData);
      let flag = arr.some((item) => {
        if (temp[item]) {
          temp = temp[item];
          return false;
        } else {
          this.$message({
            type: "error",
            message: "数据处理失败，认证存在无效值",
          });
          return true;
        }
      });
      if (!flag) {
        return temp;
      }
    },
    // delog数据处理辅助函数（递归）
    DebugDataHandle(obj, arr) {
      arr.forEach((item) => {
        if (item.parameterName && item.concreteType) {
          if (
            item.concreteType !== "Object" &&
            item.concreteType !== "ObjectCom" &&
            item.concreteType !== "Map"
          ) {
            // 有bug需要修改 需要考虑fundamentallist

            if (item.parameterType === "authport") {
              obj[item.parameterName] = "";
            } else if (item.parameterType === "fundamentallist") {
              obj[item.parameterName] = [item.example];
            } else {
              obj[item.parameterName] = item.example ? item.example : "";
            }
          } else if (
            item.concreteType === "Object" ||
            item.concreteType === "Map" ||
            item.concreteType === "ObjectCom"
          ) {
            if (item.concreteType === "Object" || item.concreteType === "Map") {
              obj[item.parameterName] = {};
              if (item.children && item.children.length) {
                this.DebugDataHandle(obj[item.parameterName], item.children);
              }
            } else if (item.concreteType === "ObjectCom") {
              obj[item.parameterName] = [];
              obj[item.parameterName].push({});
              this.DebugDataHandle(
                obj[item.parameterName][obj[item.parameterName].length - 1],
                item.children
              );
            }
          }
        }
      });
    },
    // 主表的操作按钮方法
    tableButtonHandle(val, item) {
      if (item.type === "debug") {
        this.rightDialog = true;
        this.getDebugInfoHandle(val.id, this.resultInfo).then((val) => {
          this.debugInfo = val;
        });
      } else if (item.type === "dele") {
        this.$confirm("确认删除？")
          .then(() => {
            this.deleTableHandle(val.id);
          })
          .catch(() => {});
      } else if (item.type === "edit") {
        this.$router.push({
          name: "apiAdd",
          query: { id: val.id },
        });
      }
    },
    // 点击查看
    viewHandle(row) {
      this.$router.push({ name: "apiView", query: { id: row.id } });
    },
    // 切页吗
    currentChangeHandle(pageModel) {
      this.pageModel = pageModel;
      this.$nextTick(() => {
        this.getApiModuleHandle(this.searchForm);
      });
    },
    // 点击新增
    goAddHandle() {
      this.$router.push({ name: "apiAdd" });
    },
  },
  computed: {
    // 操作框的宽度
    funWidth() {
      return this.mainFunData.length * 70;
    },
  },
  components: {
    // 所需模块
    baseNewForm,
    baseNewTable,
    basePage,
    baseRightDialog,
    vueJsonEditor,
    jsonView,
  },
  mounted() {
    // 初始化表单
    this.getApiModuleHandle();
    this.initSysSelect();
  },
  activated() {
    this.getApiModuleHandle(this.searchForm);
  },
  beforeRouteLeave(to, from, next) {
    if (
      to.path != "/middleground/jcapipz/apiview" &&
      to.path != "/middleground/jcapipz/apiAdd"
    ) {
      next();
      this.$destroy("ApiAdmin");
    } else {
      next();
    }
  },
};
</script>

<style scoped lang='scss'>
.wrap {
  height: 100vh;
  overflow: scroll;
  .searchBox {
    margin: 10px;
    padding: 15px;
    background-color: #fff;
    border-radius: 20px;
    .searchbtn {
      margin-left: 80%;
    }
  }
  .tablebox {
    margin: 10px;
    padding: 15px 15px 10px;
    background-color: #fff;
    border-radius: 20px;
    .tablebtn {
      margin-left: 20px;
    }
    .tablecontent {
      margin: 10px 20px 0;
    }
  }
  .page {
    margin-top: 20px;
  }
  .rightdalog {
    width: 100vw;
    padding: 20px;
    .debugchunk {
      margin-bottom: 20px;
      .title {
        margin-bottom: 20px;
      }
    }
  }
}
</style>

<style lang="less" scoped>
.code-json-editor {
  /* jsoneditor右上角默认有一个链接,加css去掉 */
  /deep/ .jsoneditor-poweredBy {
    display: none !important;
  }
  // /deep/ .ace_editor {
  //   height: 90vh !important;
  // }
}
</style>
