<template>
  <div>
    <!-- 查询配置 -->
    <div>
      <div ref="lxHeader">
        <LxHeader
          icon="md-apps"
          :text="$route.meta.title"
          style="margin-bottom: 10px; border: 0px; margin-top: 15px"
        >
          <div slot="content"></div>
          <slot>
            <header-content :auths="auths_auth_mixin">
              <template #search>
                <div style="display: flex">
                  <Select
                    v-model="select.filter[0].key"
                    style="width: 100px"
                    placeholder="搜索条目"
                  >
                    <Option
                      v-for="item in form"
                      :key="item.id"
                      :value="item.field"
                    >{{ item.name }}</Option
                    >
                  </Select>
                  <Select
                    v-model="select.filter[0].op"
                    style="width: 100px; margin-left: 10px"
                    placeholder="搜索条件"
                  >
                    <Option
                      v-for="item in op"
                      :key="item.value"
                      :value="item.value"
                    >{{ item.label }}</Option
                    >
                  </Select>
                  <template
                    v-if="
                      select.filter[0].op !== 'range' &&
                      !columnArrTest(select.filter[0].key)
                    "
                  >
                    <Input
                      v-model="select.filter[0].value"
                      style="width: 150px; margin-left: 10px"
                      placeholder="请填写关键词"
                    />
                  </template>
                  <template
                    v-else-if="
                      select.filter[0].op !== 'range' &&
                      columnArrTest(select.filter[0].key)
                    "
                  >
                    <Select
                      v-model="select.filter[0].value"
                      style="width: 150px; margin-left: 10px"
                      placeholder="请选择关键词"
                    >
                      <Option
                        v-for="item in getColumnParams(select.filter[0].key)"
                        :key="item.id"
                        :value="
                          getColumnField(select.filter[0].key)._relations
                            ? item[
                                getColumnField(select.filter[0].key)._relations
                                  .foreign_key
                              ]
                            : item.value
                        "
                      >{{
                          item.key ||
                          item.value ||
                          item.name ||
                          item.no ||
                          item.mingcheng ||
                          item.id
                        }}</Option
                      >
                    </Select>
                  </template>
                  <template v-else>
                    <Input
                      :value="select.filter[0].value.split(',')[0]"
                      style="width: 150px; margin-left: 10px"
                      placeholder="范围开始关键词"
                      @input="(e) => inputStartHandler(e, select.filter[0])"
                    />
                    <span
                      style="
                        margin-left: 10px;
                        display: flex;
                        align-items: center;
                      "
                    >至</span
                    >
                    <Input
                      :value="select.filter[0].value.split(',')[1]"
                      style="width: 150px; margin-left: 10px"
                      placeholder="范围结束关键词"
                      @input="(e) => inputEndHandler(e, select.filter[0])"
                    />
                  </template>
                  <Button
                    style="margin-left: 10px"
                    type="primary"
                    @click="$refs['xyTable'].getTableData(true)"
                  >查询</Button
                  >

                  <xy-selectors
                    style="margin-left: 10px"
                    @reset="reset"
                    @search="$refs['xyTable'].getTableData(true)"
                  >
                    <template>
                      <div class="select">
                        <div
                          class="select__item"
                          v-for="(item, index) in select.filter"
                          :key="`${item.value}-${index}`"
                        >
                          <p>条件{{ index + 1 }}</p>
                          <Select
                            v-model="item.key"
                            style="width: 100px"
                            placeholder="搜索条目"
                          >
                            <Option
                              v-for="item in form"
                              :key="item.id"
                              :value="item.field"
                            >{{ item.name }}</Option
                            >
                          </Select>
                          <Select
                            v-model="item.op"
                            style="width: 100px; margin-left: 10px"
                            placeholder="搜索条件"
                          >
                            <Option
                              v-for="item in op"
                              :key="item.value"
                              :value="item.value"
                            >{{ item.label }}</Option
                            >
                          </Select>
                          <template
                            v-if="
                              item.op !== 'range' && !columnArrTest(item.key)
                            "
                          >
                            <Input
                              v-model="item.value"
                              style="width: 150px; margin-left: 10px"
                              placeholder="请填写关键词"
                            />
                          </template>
                          <template
                            v-else-if="
                              item.op !== 'range' && columnArrTest(item.key)
                            "
                          >
                            <Select
                              v-model="item.value"
                              style="width: 150px; margin-left: 10px"
                              placeholder="请选择关键词"
                            >
                              <Option
                                v-for="item in getColumnParams(item.key)"
                                :key="item.id"
                                :value="
                                  getColumnField(item.key)._relations
                                    ? item[
                                        getColumnField(item.key)._relations
                                          .foreign_key
                                      ]
                                    : item.value
                                "
                              >{{
                                  item.key ||
                                  item.value ||
                                  item.name ||
                                  item.no ||
                                  item.mingcheng ||
                                  item.id
                                }}</Option
                              >
                            </Select>
                          </template>
                          <template v-else>
                            <Input
                              :value="item.value.split(',')[0]"
                              style="width: 150px; margin-left: 10px"
                              placeholder="范围开始关键词"
                              @input="(e) => inputStartHandler(e, item)"
                            />
                            <span style="margin-left: 10px">至</span>
                            <Input
                              :value="item.value.split(',')[1]"
                              style="width: 150px; margin-left: 10px"
                              placeholder="范围结束关键词"
                              @input="(e) => inputEndHandler(e, item)"
                            />
                          </template>
                          <el-button
                            v-if="index !== 0"
                            size="small"
                            type="danger"
                            icon="el-icon-delete"
                            circle
                            style="margin-left: 10px"
                            @click="select.filter.splice(index, 1)"
                          ></el-button>
                        </div>
                      </div>
                      <div class="add-btn">
                        <el-button
                          size="small"
                          type="primary"
                          icon="el-icon-plus"
                          circle
                          @click="
                            select.filter.push({ key: '', op: '', value: '' })
                          "
                        ></el-button>
                        <span>新增一条</span>
                      </div>
                    </template>
                  </xy-selectors>
                </div>
              </template>
              <template #create>
                <Button
                  type="primary"
                  @click="
                    $refs['dialog'].setType('add'), $refs['dialog'].show()
                  "
                >新增</Button
                >
              </template>
              <template #import>
                <Button type="primary" @click="$refs['imports'].show()"
                >导入</Button
                >
              </template>
              <template #export>
                <Button
                  type="primary"
                  @click="exportExcel(new Date().getTime().toString())"
                >导出</Button
                >
              </template>
            </header-content>
          </slot>
        </LxHeader>
      </div>
    </div>
    <!--$refs['drawer'].setId(row.id);
              $refs['drawer'].show();-->
    <xy-table
      :btn-width="240"
      :auths="auths_auth_mixin"
      :delay-req="true"
      :destroy-action="destroy"
      ref="xyTable"
      :border="true"
      :action="index"
      :req-opt="tableSelect"
      :destroy-req-opt="select"
      :table-item="table"
      @detail="
        (row) => {
          $router.push({
            path: $route.path + '/detail/' + row.id,
          });
        }
      "
      @editor="
        (row) => {
          $refs['dialog'].setId(row.id);
          $refs['dialog'].setType('editor');
          $refs['dialog'].show();
        }
      "
    >
      <template #callback="{ row }">
        <Button
          size="small"
          type="primary"
          @click="
            $refs['callback'].setId(row.id),
              $refs['callback'].setType('add'),
              $refs['callback'].show()
          "
        >反馈</Button
        >
      </template>
      <template #distribute="{ row }">
        <Button
          v-if="row.status === 1"
          size="small"
          type="primary"
          @click="setTransferStatus(2,row)"
        >下发</Button
        >
        <Button
          v-if="row.status === 2"
          size="small"
          type="primary"
          ghost
          @click="setTransferStatus(1,row)"
        >取消</Button
        >
      </template>
    </xy-table>

    <addGroup
      :table-name="customForm.tableName"
      :form-info="form"
      ref="dialog"
      @refresh="$refs['xyTable'].getTableData()"
    >
    </addGroup>
    <imports
      :table-name="customForm.tableName"
      :form-info="form"
      ref="imports"
      @refresh="$refs['xyTable'].getTableData()"
    ></imports>

  </div>
</template>

<script>
import { index as fieldIndex } from "@/api/system/customFormField";
import { authMixin } from "@/mixin/authMixin";
import { index, destroy, save } from "@/api/system/baseForm";
import { op } from "@/const/op";
import { download } from "@/utils/downloadRequest";
import { getparameter } from "@/api/system/dictionary";
import { show } from "@/api/system/customForm";
import * as XLSX from "xlsx";
import { saveAs } from "file-saver";
import { listdept } from "@/api/system/department";

import addGroup from "./component/addGroup.vue";
import LxHeader from "@/components/LxHeader/index.vue";
import headerContent from "@/components/LxHeader/XyContent.vue";
import imports from "./component/imports.vue";
import { deepCopy } from "@/utils";
export default {
  components: {
    LxHeader,
    addGroup,
    headerContent,
    imports,
  },
  mixins: [authMixin],
  provide: {
    formStore: () => this.form,
  },
  data() {
    return {
      op,
      select: {
        table_name: "",
        filter: [
          {
            key: "",
            op: "",
            value: "",
          },
        ],
      },
      selectQuery: [],
      form: [],
      table: [],
      customForm: {
        customFormId: "",
        tableName: "",
      },
    };
  },
  methods: {
    setTransferStatus (status,row) {
      let copyRow = deepCopy(row);
      copyRow.status = status;
      for (let key in copyRow) {
        if (/_relation/g.test(key)) {
          delete copyRow[key]
        }
      }
      save({
        table_name: 'transfers',
        ...copyRow
      }).then(_ => this.$refs['xyTable'].getTableData())
    },

    index,
    destroy,
    download,
    reset() {
      this.select.filter.splice(1);
      this.select.filter[0] = {
        key: "",
        op: "",
        value: "",
      };
    },

    async exportExcel(sheetName) {
      const res = await index(
        Object.assign(this.select, { page: 1, page_size: 9999 })
      );
      if (res.data) {
        let headers = this.form.map((i) => {
          return {
            key: i.field,
            title: i.name,
          };
        });
        const data = res.data.map((row) =>
          headers.map((header) => row[header.key])
        );
        data.unshift(headers.map((header) => header.title));
        const wb = XLSX.utils.book_new();
        const ws = XLSX.utils.aoa_to_sheet(data);
        XLSX.utils.book_append_sheet(wb, ws, sheetName);
        const wbout = XLSX.write(wb, {
          bookType: "xlsx",
          bookSST: true,
          type: "array",
        });
        saveAs(
          new Blob([wbout], { type: "application/octet-stream" }),
          `${sheetName}.xlsx`
        );
      }
    },

    //target要为内存地址引用类型
    inputStartHandler(e, target) {
      let temp = target?.value.split(",")[1];
      target.value = `${e},${temp ? temp : ""}`;
    },
    inputEndHandler(e, target) {
      let temp = target?.value.split(",")[0];
      target.value = `${temp ? temp : ""},${e}`;
    },

    async getFormDetail() {
      if (this.$route.meta.params?.custom_form) {
        let decode = decodeURIComponent(this.$route.meta.params?.custom_form);
        try {
          let custom_form = JSON.parse(decode);
          this.customForm.customFormId = custom_form.custom_form_id;
          this.customForm.tableName = custom_form.table_name;
          this.select.table_name = custom_form.table_name;
        } catch (err) {
          console.warn(err);
        }
      }
      if (this.$route.meta.params?.select) {
        try {
          this.selectQuery = JSON.parse(
            decodeURIComponent(this.$route.meta.params?.select)
          );
        } catch (err) {
          console.warn(err);
        }
      }

      const res = await show({ id: this.customForm.customFormId }, false);

      //字段处理
      //初始表白名单
      let baseTable = new Map([
        [
          "departments",
          async () => {
            const res = await listdept();
            return res;
          },
        ],
        ["admins", []],
      ]);
      let { fields, relation } = res;
      let fieldRes = fields.sort((a, b) => a.sort - b.sort);
      if (
        !fields ||
        !relation ||
        !fields instanceof Array ||
        !relation instanceof Array
      ) {
        throw new Error("fields或relation格式错误");
      }
      fieldRes?.forEach((i, index) => {
        i._relations = relation.find((j) => j.custom_form_field === i.field);
        if (i.select_item && typeof i.select_item === "object") {
          let keys = Object.keys(i.select_item);
          if (keys.length > 0) {
            i._params = keys.map((key) => {
              return {
                key,
                value: /^\d*$/.test(i.select_item[key])
                  ? Number(i.select_item[key])
                  : i.select_item[key],
              };
            });
          }
        }
        if (i.edit_input === "file" || i.edit_input === "files") {
          return;
        }
        if (i._relations) {
          if (baseTable.get(i._relations.link_table_name)) {
            baseTable
              .get(i._relations.link_table_name)()
              .then((res) => (i._params = res));
          } else {
            i._params = i._relations.parameter_id
              ? getparameter({ id: i._relations.parameter_id }, false).then(
                (res) => {
                  i._params = res.detail;
                }
              )
              : this.index({
                table_name: i._relations.link_table_name,
                page: 1,
                page_size: 9999,
              }).then((res) => {
                i._params = res.data;
              });
          }
        }
      });
      this.form = fields;
      this.form
        ?.filter((i) => i.list_show)
        .forEach((i) => {
          let linkOb = {};

          if (i.edit_input === "richtext") {
            linkOb.customFn = (row) => {
              return (
                <div
                  style={{ "max-height": "55px", overflow: "scroll" }}
                  domPropsInnerHTML={row[i.field]}
                ></div>
              );
            };
          }
          if (
            i.select_item &&
            typeof i.select_item === "object" &&
            !(i.select_item instanceof Array)
          ) {
            let keys = Object.keys(i.select_item);
            linkOb.customFn = (row) => {
              let paramMap = new Map();
              keys.forEach((key) => {
                paramMap.set(i.select_item[key], key);
              });

              return <span>{paramMap.get(row[i.field]?.toString())}</span>;
            };
          }
          if (i._relations) {
            let { link_relation, foreign_key, link_with_name } = i._relations;
            if (link_relation === "newHasOne" || link_relation === "hasOne") {
              linkOb.customFn = (row) => {
                if (i.edit_input === "file") {
                  return (
                    <a
                      download={row[link_with_name]?.original_name}
                      href={row[link_with_name]?.url}
                    >
                      {row[link_with_name]?.original_name}
                    </a>
                  );
                } else {
                  return (
                    <span>
                      {row[link_with_name]?.name ||
                        row[link_with_name]?.no ||
                        row[link_with_name]?.value}
                    </span>
                  );
                }
              };
            }

            if (link_relation === "hasMany" || link_relation === "newHasMany") {
              linkOb.customFn = (row) => {
                if (i.edit_input === "files") {
                  return (
                    <div style="display: flex;flex-direction: column;">
                      {row[link_with_name]?.map((o) => (
                        <a>{o?.original_name || o?.name}</a>
                      ))}
                    </div>
                  );
                } else {
                  return (
                    <div>
                      {row[link_with_name]?.map((o) => (
                        <p>
                          {o?.name ||
                            o?.no ||
                            o?.value ||
                            o?.biaoti ||
                            o?.mingcheng || o?.telephone || o?.id}
                        </p>
                      ))}
                    </div>
                  );
                }
              };
            }
          }

          let alignLeft = [];
          this.table.push(
            Object.assign(
              {
                prop: i.field,
                label: i.name,
                width: i.width,
                align: alignLeft.find((m) => m === i.field) ? "left" : "center",
                fixed: i.is_fixed,
              },
              linkOb
            )
          );
        });
      this.table.unshift({
        type: "index",
        width: 60,
        label: "序号",
      });
    },
  },

  computed: {
    columnArrTest() {
      return function (field) {
        return this.form.find((i) => i.field === field)
          ? this.form.find((i) => i.field === field).search_input ===
          "checkbox" ||
          this.form.find((i) => i.field === field).search_input === "radio"
          : false;
      };
    },
    getColumnField() {
      return function (field) {
        return this.form.find((i) => i.field === field)
          ? this.form.find((i) => i.field === field)
          : {};
      };
    },
    getColumnParams() {
      return function (field) {
        return this.form.find((i) => i.field === field)
          ? this.form.find((i) => i.field === field)._params
          : [];
      };
    },

    tableSelect() {
      let filter = [...this.select.filter, ...this.selectQuery];
      return {
        ...this.select,
        filter,
      };
    },
  },
  created() {
    this.getFormDetail();
  },
};
</script>

<style scoped lang="scss">
.select {
  &__item {
    & > p {
      display: inline-block;
      width: 80px;
      text-align: center;
    }

    & + div {
      margin-top: 6px;
    }
  }
}
.add-btn {
  display: flex;
  justify-content: center;
  align-items: center;

  margin-top: 10px;
  & > span {
    padding: 0 10px;
  }
}

a {
  color: red;
  text-decoration: none;
  transition: all 0.2s;
}

a:hover {
  color: red;
  text-decoration: underline;
}
</style>
