<template>
  <div :class="[hasTreeFieldInQueryForm ? 'page-container' : 'app-container']">
    <div v-if="hasTreeFieldInQueryForm" class="left-container">
      <AnjiTree
        ref="queryFormTree"
        v-model.trim="queryParams[queryFormTreeField.field]"
        :is-open="queryFormTreeField.anjiTreeOption.isOpen"
        :enable-filter="queryFormTreeField.anjiTreeOption.enableFilter"
        :label-name="queryFormTreeField.label"
        :url="queryFormTreeField.anjiTreeOption.url"
        @node-click="handleTreeNodeCheck"
      />
    </div>
    <div class="right-container">
      <!-- 查询表单开始 -->
      <el-form
        ref="formSearch"
        :model="queryParams"
        label-width="100px"
        v-permission="option.buttons.query.permission"
      >
        <el-row>
          <el-col
            v-for="(item, index) in queryFormFieldExcludeTree"
            :key="item.field"
            :span="queryFormFieldSpan(item)"
          >
            <el-form-item
              v-if="index <= 2 || (index > 2 && queryParams.showMoreSearch)"
              :label="item.label"
              :rules="item.rules"
              :prop="item.field"
            >
              <!-- 输入框 -->
              <el-input
                v-if="
                  item.inputType == 'input' || item.inputType == 'input-number'
                "
                v-model.trim="queryParams[item.field]"
                :placeholder="item.placeholder || '请输入'"
                :clearable="item.clearable !== false"
                :disabled="item.disabled"
                @change="value => queryFormChange(item.field, value)"
              />
              <!-- 开关 -->
              <el-switch
                v-else-if="item.inputType == 'switch'"
                v-model.trim="queryParams[item.field]"
                :disabled="item.disabled"
                :active-value="item.switchOption.disableValue"
                :inactive-value="item.switchOption.enableValue"
                active-color="#5887fb"
                inactive-color="#ccc"
                @change="value => queryFormChange(item.field, value)"
              />
              <!-- 下拉框 -->
              <anji-select
                v-else-if="item.inputType == 'anji-select'"
                v-model.trim="queryParams[item.field]"
                :multiple="item.anjiSelectOption.multiple"
                :dict-code="item.anjiSelectOption.dictCode"
                :url="item.anjiSelectOption.url"
                :method="item.anjiSelectOption.method"
                :query-param="item.anjiSelectOption.queryParam"
                :option="item.anjiSelectOption.option"
                :label="item.anjiSelectOption.label"
                :disabled-options="item.anjiSelectOption.disabledOptions"
                :disabled="item.disabled"
                :merge-label="item.anjiSelectOption.mergeLabel"
                @change="value => queryFormChange(item.field, value)"
              />
              <!-- 日期时间框  -->
              <el-date-picker
                v-else-if="item.inputType.indexOf('date') >= 0"
                v-model="queryParams[item.field]"
                style="width: 100%"
                :placeholder="item.placeholder || '请选择'"
                :type="item.inputType"
                :clearable="item.clearable !== false"
                @change="value => queryFormChange(item.field, value)"
              />
              <!-- 待扩展的表单类型,请自行扩展 -->
              <el-input
                v-else
                placeholder="组件不支持此类型表单请至组件内部自行扩展"
                disabled
              />
            </el-form-item>
          </el-col>

          <el-col :span="6" style="text-align: center">
            <el-button type="primary" @click="handleQueryForm('query')"
              >查询</el-button
            >
            <el-button type="danger" @click="handleResetForm()">重置</el-button>
            <a
              v-if="queryFormFieldExcludeTree.length > 3"
              style="margin-left: 8px"
              @click="handleToggleMoreSearch"
            >
              {{ queryParams.showMoreSearch == true ? "收起" : "展开" }}
              <i
                :class="
                  queryParams.showMoreSearch
                    ? 'el-icon-arrow-up'
                    : 'el-icon-arrow-down'
                "
              />
            </a>
          </el-col>
        </el-row>
      </el-form>
      <!-- 查询表单结束 -->

      <!-- 批量操作 -->
      <slot name="buttonLeftOnTable" />
      <el-button
        v-if="
          option.buttons.add.isShow == undefined
            ? true
            : option.buttons.add.isShow
        "
        v-permission="option.buttons.add.permission"
        type="primary"
        icon="el-icon-plus"
        @click="handleOpenEditView('add')"
        >新增</el-button
      >
      <el-button
        v-if="
          option.buttons.delete.isShow == undefined
            ? true
            : option.buttons.delete.isShow
        "
        v-permission="option.buttons.delete.permission"
        :disabled="disableBatchDelete"
        type="danger"
        icon="el-icon-delete"
        @click="handleDeleteBatch()"
        >删除</el-button
      >

      <!-- 表格开始 -->
      <el-table
        class="anji_curd_table"
        :data="records"
        border
        @selection-change="handleSelectionChange"
        @sort-change="handleSortChange"
      >
        <!--多选-->
        <el-table-column fixed type="selection" width="50" align="center" />
        <!--隐藏列-->
        <el-table-column v-if="tableExpandColumns.length > 0" type="expand">
          <template slot-scope="scope">
            <p
              v-for="item in tableExpandColumns"
              :key="item.field"
              class="table-expand-item"
            >
              <span class="titel"> {{ item.label }}: </span>
              <span>{{ scope.row[item.field] }}</span>
            </p>
          </template>
        </el-table-column>
        <!--序号-->
        <el-table-column label="序号" min-width="50" align="center">
          <template slot-scope="scope">
            {{
              queryParams.pageSize * (queryParams.pageNumber - 1) +
                scope.$index +
                1
            }}
          </template>
        </el-table-column>

        <template v-for="item in option.columns">
          <el-table-column
            v-if="item.tableHide != true && item.columnType != 'expand'"
            :key="item.field"
            :prop="item.field"
            :label="fieldLabel(item)"
            :min-width="item.minWidth || 110"
            :sortable="item.sortable"
            :show-overflow-tooltip="true"
            align="center"
          >
            <template slot-scope="scope">
              <div v-if="item.columnType == 'imgPreview'">
                <!-- 图片缩略图-->
                <el-image
                  style="width: 25%; height: 50%"
                  fit="contain"
                  :src="scope.row[item.field]"
                  :preview-src-list="[scope.row[item.field]]"
                />
              </div>
              <div v-else>
                <span v-if="item.inputType == 'switch' && !item.colorStyle">
                  <el-switch
                    v-model.trim="scope.row[item.field]"
                    :active-value="1"
                    :inactive-value="0"
                    active-color="#5887fb"
                    inactive-color="#ccc"
                    @change="switchChange(scope.row, item.switchOption)"
                  />
                </span>
                <!-- 带单位 -->
                <span v-else-if="item.inputType == 'anji-input'">{{
                  fieldValueByAnjiInput(scope.row[item.field], item)
                }}</span>
                <!--表格 a 合并 b上-->
                <span v-else-if="item.mergeColumn"
                  >{{ scope.row[item.field] }}({{
                    scope.row[item.mergeColumn]
                  }})</span
                >
                <!-- 没有单位 -->
                <span
                  v-else-if="item.colorStyle"
                  :class="item.colorStyle[scope.row[item.editField]]"
                  >{{ fieldValueByRowRenderer(scope.row, item) }}</span
                >
                <span v-else>{{
                  fieldValueByRowRenderer(scope.row, item)
                }}</span>
                <!-- 正常展示模式
                <div v-if="!item.custom">
                  是第一列数据 && 需要高亮字段不为false 高亮并且可以点击
                  <span v-if="!index && item.operate !== false" class="view" @click="handleOpenEditView('view', scope.row)">{{ scope.row[item.field] }}</span>
                  <span v-else>{{ scope.row[item.field] }}</span>
                </div>
                -->
                <!-- 自定义展示数据
                <div v-else v-html="item.renderer(scope.row)" />-->
              </div>
            </template>
          </el-table-column>
        </template>
        <!--操作栏-->
        <el-table-column
          align="center"
          fixed="right"
          label="操作"
          :width="
            option.buttons.customButton &&
            option.buttons.customButton.operationWidth
              ? option.buttons.customButton.operationWidth
              : 100
          "
        >
          <template slot-scope="scope">
            <slot name="edit" :msg="scope.row" />
            <el-button
              v-if="
                (option.buttons.query.isShow == undefined
                  ? true
                  : option.buttons.query.isShow) &&
                  hasPermission(option.buttons.edit.permission) == false
              "
              type="text"
              size="small"
              @click="handleOpenEditView('view', scope.row)"
              v-permission="option.buttons.query.permission"
              >查看</el-button
            >
            <el-button
              v-if="
                option.buttons.edit.isShow == undefined
                  ? true
                  : option.buttons.edit.isShow
              "
              type="text"
              size="small"
              @click="handleOpenEditView('edit', scope.row)"
              v-permission="option.buttons.edit.permission"
              >编辑</el-button
            >
            <el-button
              v-if="
                hasRowCustomButton == false &&
                option.buttons.delete.isShow == undefined
                  ? true
                  : option.buttons.edit.isShow
              "
              type="text"
              size="small"
              @click="handleDeleteBatch(scope.row)"
              v-permission="option.buttons.delete.permission"
              >删除</el-button
            >
            <el-dropdown v-if="hasRowCustomButton" trigger="click">
              <span class="el-dropdown-link">
                更多<i class="el-icon-caret-bottom el-icon--right" />
              </span>
              <el-dropdown-menu slot="dropdown">
                <el-dropdown-item class="clearfix">
                  <slot name="rowButton" :msg="scope.row" />
                  <el-button
                    v-if="
                      option.buttons.delete.isShow == undefined
                        ? true
                        : option.buttons.edit.isShow
                    "
                    type="text"
                    size="small"
                    @click="handleDeleteBatch(scope.row)"
                    v-permission="option.buttons.delete.permission"
                    >删除</el-button
                  >
                </el-dropdown-item>
              </el-dropdown-menu>
            </el-dropdown>
          </template>
        </el-table-column>
      </el-table>
      <div class="pagination">
        <el-pagination
          v-show="total > 0"
          background
          :current-page.sync="queryParams.pageNumber"
          :page-sizes="$pageSizeAll"
          :page-size="queryParams.pageSize"
          layout="total, prev, pager, next, jumper, sizes"
          :total="total"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
        <div>
          <slot name="tableSelectionBtn" :selection="checkRecords" />
        </div>
      </div>

      <!-- 表格结束 -->

      <EditDialog
        ref="edit"
        :option="option"
        :model-type="editDialogModelType"
        :visible="editDialogOpen"
        :row-data="editDialogRowData"
        @closeEvent="editDialogClosedEvent"
      >
        <template v-slot:customCard>
          <slot name="cardInEditPage" />
        </template>
        <template slot="editBtn" slot-scope="scope">
          <slot name="editBtnPage" :rowData="scope" />
        </template>
      </EditDialog>
    </div>
    <slot name="pageSection" />
  </div>
</template>
<script>
import AnjiTree from "@/components/AnjiPlus/anji-tree.vue";
import EditDialog from "./edit";
import request from "@/utils/request";
export default {
  components: {
    EditDialog,
    AnjiTree
  },
  props: {
    option: {
      require: true,
      type: Object,
      default: () => {
        return {
          // 查询表单条件
          queryFormFields: [],
          // 按钮
          buttons: {
            query: {},
            edit: {},
            delete: {},
            add: {}
          },
          // 表格列
          columns: [],
          queryFormChange: (fileName, val) => {}
        };
      }
    }
  },
  data() {
    return {
      // 查询表单提交的值
      queryParams: {
        showMoreSearch: false, // 是否展开更多搜索条件
        pageNumber: 1,
        pageSize: 10,
        order: "",
        sort: ""
      },

      checkRecords: [], // 表格中当前选中的记录
      records: [], // 接口返回的记录列表
      total: 0, // 接口返回的总条数

      // 编辑详情弹框
      editDialogOpen: false, // 新建时主动打开编辑弹框
      editDialogRowData: {}, // 编辑时的主键
      editDialogModelType: "view", // 编辑 查看

      hasRowCustomButton: false // 除了编辑删除外,还有自定义的行按钮
    };
  },
  computed: {
    // 左侧树形查询条件
    queryFormTreeField() {
      var treeField = this.option.queryFormFields.find(
        item => item["inputType"] == "anji-tree"
      );
      return treeField;
    },
    // 查询条件里是否有树形控件
    hasTreeFieldInQueryForm() {
      return this.isNotBlank(this.queryFormTreeField);
    },
    // 不包含树形控件的查询条件
    queryFormFieldExcludeTree() {
      var treeFields = this.option.queryFormFields.filter(
        item => item["inputType"] != "anji-tree"
      );
      return treeFields;
    },
    // 主键的列名
    primaryKeyFieldName() {
      var primaryKey = this.option.columns.find(
        item => item["primaryKey"] == true
      );
      if (primaryKey != null) {
        return primaryKey["field"];
      } else {
        return null;
        console.warn(
          "在columns中查找primaryKey=true失败,会导致查询详情和删除失败"
        );
      }
    },

    // 表格中可展开的列
    tableExpandColumns() {
      var expandColumns = this.option.columns.filter(
        item => item["columnType"] == "expand"
      );
      return expandColumns;
    },

    // 是否可以批量删除
    disableBatchDelete() {
      return this.checkRecords.length <= 0;
    }
  },
  created() {
    // 为查询框中所有input加上默认值
    this.option.queryFormFields.forEach(item => {
      // 动态添加属性
      this.$set(this.queryParams, item.field, item.defaultValue || null);
    });
    // 查询列表
    this.handleQueryForm("query");
    this.queryFormChange();
  },
  mounted() {
    if (this.$scopedSlots["rowButton"] != null) {
      this.hasRowCustomButton = true;
    } else {
      this.hasRowCustomButton = false;
    }
  },
  methods: {
    queryFormFieldSpan(item) {
      // console.log(item)

      if (item.span != null) {
        return item.span;
      } else {
        return 6;
      }
      // let rowLength = this.option.queryFormFields.length;
      // console.log(rowLength, "ss")
      // console.log(rowLength % 3)
      // if (rowLength <= 3) {
      //   return 6
      // }
      // else if (rowLength % 3 == 0) {
      //   return 8
      // } else if (rowLength > 6) {
      //   return 8
      // }
    },
    // 切换更多搜索条件
    handleToggleMoreSearch() {
      this.queryParams.showMoreSearch = !this.queryParams.showMoreSearch;
    },
    // 列上排序切换
    handleSortChange(column) {
      // {column: {…}, prop: "orgCode", order: "ascending"}
      if (column == null || column.prop == null) {
        console.warn("排序字段名prop为空,无法排序");
        return;
      }
      var sort = column.prop; // 列表查询默认排序列
      var order = column.order == "ascending" ? "ASC" : "DESC";
      this.queryParams["sort"] = sort;
      this.queryParams["order"] = order;
      this.handleQueryForm("query");
    },
    // 查询按钮
    handleQueryForm(from) {
      // 如果是点查询按钮,把树的查询属性去掉
      if (from == "query") {
        if (this.hasTreeFieldInQueryForm) {
          delete this.queryParams[this.queryFormTreeField.field];
        }
      }
      // 如果是点树查询,把查询区里的属性去掉
      if (from == "tree") {
        if (this.hasTreeFieldInQueryForm) {
          var treeVal = this.queryParams[this.queryFormTreeField.field];
          this.queryParams = {
            pageNumber: 1,
            pageSize: 10
          };
          this.queryParams[this.queryFormTreeField.field] = treeVal;
        }
      }
      // 默认的排序
      if (
        this.isBlank(this.queryParams["order"]) &&
        this.isNotBlank(this.option.buttons.query.order)
      ) {
        this.queryParams["sort"] = this.option.buttons.query.sort;
        this.queryParams["order"] = this.option.buttons.query.order;
      }
      this.queryParams.pageNumber = 1;
      this.handleQueryPageList();
    },
    // 列表查询
    async handleQueryPageList() {
      var params = this.queryParams;
      // 将特殊参数值urlcode处理 var params = this.urlEncodeObject(this.queryParams, 'order,sort')
      const { data, code } = await this.option.buttons.query.api(params);
      if (code != "200") return;
      this.records = data.records;
      this.total = data.total;
    },
    // 重置
    handleResetForm() {
      this.queryParams = {
        pageNumber: 1,
        pageSize: 10
      };
      // this.$refs['queryForm'].resetFields()
      // this.records = []
      // this.total = 0
    },
    // 树形查询条件点击回调
    handleTreeNodeCheck() {
      this.handleQueryForm("tree");
      // 为新建页面的对应属性值,绑定上对应的默认值
      var treeFieldName = this.queryFormTreeField["field"];
      for (var i = 0; i < this.option.columns.length; i++) {
        var item = this.option.columns[i];
        if (
          item["editField"] == treeFieldName ||
          item["field"] == treeFieldName
        ) {
          this.$set(
            this.option.columns[i],
            "defaultValue",
            this.queryParams[treeFieldName]
          );
          break;
        }
      }
    },
    // 编辑和查看操作
    handleOpenEditView(modelType, row) {
      if (modelType == "view" || modelType == "edit") {
        this.editDialogRowData = row;
      }
      this.editDialogModelType = modelType;
      if (modelType == "add") {
        // 新增模式,不需要查询数据详情,直接打开
        this.editDialogOpen = true;
      }
      const obj = {
        type: modelType,
        value: row
      };
      this.$emit("handleCustomValue", obj);
    },
    // 弹框被关闭时的回调事件
    editDialogClosedEvent(value) {
      // 把列表页中弹框打开标记改成已关闭
      this.editDialogOpen = false;
      // 关闭弹出框时,如果有树,刷新下
      if (
        this.hasTreeFieldInQueryForm &&
        this.$refs.queryFormTree != null &&
        !value
      ) {
        this.$refs.queryFormTree.queryData();
      }
      this.handleQueryPageList();
      // 关闭时 清空表单的验证规则
      this.$refs.edit.$refs.mainForm.$refs.editForm.resetFields();
    },
    // 批量删除
    handleDeleteBatch(row) {
      var ids = [];
      if (row != null) {
        ids.push(row[this.primaryKeyFieldName]); // 删除指定的行
      } else {
        // 批量删除选中的行
        ids = this.checkRecords.map(item => item[this.primaryKeyFieldName]);
      }
      this.$confirm("删除确认", "确认要删除吗?", {
        type: "warning",
        confirmButtonClass: "delete_sure",
        cancelButtonClass: "el-button--danger is-plain"
      })
        .then(() => {
          this.option.buttons.delete.api(ids).then(res => {
            // {code: "200", message: "操作成功", data: true}
            this.checkRecords = [];
            // 关闭弹出框时,如果有树,刷新下
            if (
              this.hasTreeFieldInQueryForm &&
              this.$refs.queryFormTree != null
            ) {
              this.$refs.queryFormTree.queryData();
            }
            this.handleQueryPageList();
          });
        })
        .catch(e => {
          e;
        });
    },

    // 选择项改变时
    handleSelectionChange(val) {
      this.checkRecords = val;
    },
    // 页码改变
    handleCurrentChange(pageNumber) {
      this.queryParams.pageNumber = pageNumber;
      this.handleQueryPageList();
    },
    // 每页size改变时
    handleSizeChange(val) {
      this.queryParams.pageNumber = 1;
      this.queryParams.pageSize = val;
      this.handleQueryPageList();
    },
    // table列文件缩略图
    thumbnailUrl(row, field) {
      // return 'http://10.108.3.123:9090/tms/file/download/79ee7e8b-2a9a-4142-b06d-706ac8089205'
      // if (row.filePath) {
      //   if (row.filePath.endsWith('xlsx') || row.filePath.endsWith('xls')) {
      //     return fileExcel;
      //   } else if (row.filePath.endsWith('pdf')) {
      //     return filePdf;
      //   }
      //   return process.env.VUE_APP_BASE_API + '/tms/file/download/' + row.fileId;
      // } else {
      //   return logo;
      // }
    },
    // 带单位的列,需要转换
    fieldLabel(columnConfig) {
      if (columnConfig == null) {
        return "";
      }
      if (
        columnConfig.inputType == "anji-input" &&
        columnConfig.anjiInput != null
      ) {
        return `${columnConfig.label}(${columnConfig.anjiInput.unit})`;
      } else {
        return columnConfig.label;
      }
    },
    // 带单位的输入框
    fieldValueByAnjiInput(value, columnConfig) {
      if (columnConfig == null) {
        return value;
      }
      if (
        columnConfig.inputType == "anji-input" &&
        columnConfig.anjiInput != null
      ) {
        return value / columnConfig.anjiInput.conversion;
      } else {
        return value;
      }
    },
    // 带表格列格式化的值
    fieldValueByRowRenderer(row, columnConfig) {
      if (
        columnConfig == null ||
        typeof columnConfig.fieldTableRowRenderer != "function"
      ) {
        return row[columnConfig.field];
      } else {
        return columnConfig.fieldTableRowRenderer(row);
      }
    },
    // 暴露给外部crud页面,回传saveForm的值
    getMainEntity() {
      return this.$refs.edit.getSaveForm();
    },
    setMainEntity(object) {
      this.$refs.edit.setSaveForm(object);
    },
    async switchChange(val, api) {
      request({
        url: api.url,
        method: "put",
        headers: { noPrompt: false },
        data: [val.id]
      }).then(response => {
        this.handleQueryPageList();
      });
    },
    queryFormChange(fileName, fieldVal) {
      if (typeof this.option.queryFormChange == "function") {
        this.option.queryFormChange(this.queryParams, fileName, fieldVal);
      }
    }
  }
};
</script>

<style scoped lang="scss">
.style-btn {
  pointer-events: none;
}
.page-container {
  height: 100%;
  position: relative;
  .left-container {
    width: 20%;
    position: absolute;
    top: 0;
    left: 0;
    background: #fff;
    border-radius: 4px 0px 0px 4px;
    padding: 20px 20px 0;
    overflow: hidden;
    overflow-y: auto;
    height: 100%;
  }
  .right-container {
    width: calc(80% - 5px);
    position: absolute;
    top: 0;
    right: 0;
    background: #fff;
    border-radius: 0px 4px 4px 0px;
    padding: 20px 20px 0;
    height: 100%;
  }
}
.el-table .cell,
.el-table td div {
  overflow: hidden;
  text-overflow: ellipsis;
}
.el-dropdown {
  font-size: 12px;
  display: inline;
  color: #5887fb;
  cursor: pointer;
}
.el-dropdown-menu--mini .el-dropdown-menu__item {
  min-width: 80px;
  max-width: 110px;
  float: right;
  .el-button--text {
    float: right;
  }
  &:hover {
    background: none !important;
  }
  .el-button--mini {
    float: right;
  }
  .el-button + .el-button {
    margin-left: 0 !important;
    float: right;
  }
}
.pagination {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  margin-top: 20px;
}
.anji_curd_table {
  margin-top: 20px;
}
</style>