<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 clearable v-model="select.filter[1].value" placeholder="请选择类别" style="width: 140px;margin-left: 6px;">
                    <Option v-for="item in abilities" :value="item.value">{{ item.key }}</Option>
                  </Select>
                  <Input style="width: 140px;margin-left: 6px;" clearable v-model="select.filter[0].value" placeholder="搜索内容"/>

                  <Button
                    style="margin-left: 10px"
                    type="primary"
                    @click="$refs['xyTable'].getTableData(true)"
                  >查询</Button
                  >
                </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>
              <Button type="primary" @click="cloneTransfer">克隆调令</Button>
              <template #distribute>
                <Button type="primary" @click="pickNoDistribute">勾选当日未下发</Button>
                <Button type="primary" @click="distributeTransfers">批量下发</Button>
              </template>
            </header-content>
          </slot>
        </LxHeader>
      </div>
    </div>
    <!--$refs['drawer'].setId(row.id);
              $refs['drawer'].show();-->
    <el-row :gutter="10">
      <el-col :span="4">
        <el-tree :data="equipments"
                 node-key="id"
                 :style="{ 'max-height':  treeHeight, 'overflow': 'scroll' }"
                 ref="elTree"
                 :props="{ children: 'children', label: 'name' }"
                 show-checkbox
                 @check="handleCheckChange">
        </el-tree>
      </el-col>
      <el-col :span="20">
        <xy-table
          :btnCondition="btnCondition"
          :span-method="objectSpanMethod"
          :format-list-data="mergeData"
          :is-page="false"
          :btn-width="360"
          :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 #adjust="{ row }">
            <template v-if="[2,3,4,5,6].find(i => i === row.status)">
              <Button
                size="small"
                type="primary"
                @click="
            $refs['adjust'].setId(row.id),
              $refs['adjust'].setType('editor'),
              $refs['adjust'].show()
          "
              >调整</Button
              >
            </template>
          </template>
          <template #callback="{ row }">
            <Button
              size="small"
              type="primary"
              @click="
            $refs['callback'].setId(row.id),
              $refs['callback'].setType('add'),
              $refs['callback'].show()
          "
            >反馈</Button
            >
          </template>
          <template #oa="{ row }">
            <Button
              size="small"
              type="primary"
              @click="toOa(row)"
            >发起流程</Button
            >
          </template>
          <template #distribute="{ row }">
            <Button
              v-if="row.status === 1 || row.status === 0"
              size="small"
              type="primary"
              @click="setTransferStatus(2,row)"
            >下发</Button
            >
          </template>
          <template #cancel="{ row }">
            <Button
              v-if="row.status === 2"
              size="small"
              type="primary"
              ghost
              @click="setTransferStatus(0,row)"
            >取消</Button
            >
          </template>
        </xy-table>
      </el-col>
    </el-row>

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

    <callback ref="callback"></callback>
    <adjust :areas="areas" :abilities="abilities" ref="adjust" @refresh="$refs['xyTable'].getTableData()"></adjust>
  </div>
</template>

<script>
import { getOaToken } from "@/api/other";
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 { show as formFieldShow } from "@/api/system/customFormField"
import * as XLSX from "xlsx";
import { saveAs } from "file-saver";
import { listdept } from "@/api/system/department";

import dialoger from "@/views/component/dialog.vue";
import LxHeader from "@/components/LxHeader/index.vue";
import headerContent from "@/components/LxHeader/XyContent.vue";
import drawer from "@/views/component/drawer.vue";
import imports from "@/views/component/imports.vue";
import callback from "@/views/order/component/callback.vue";
import adjust from "@/views/order/component/adjust.vue";
import {deepCopy} from "@/utils";
import {mergeTableRow} from "@/utils/mergeTableRow";
export default {
  components: {
    LxHeader,
    dialoger,
    headerContent,
    drawer,
    imports,
    callback,
    adjust
  },
  mixins: [authMixin],
  provide: {
    formStore: () => this.form,
    areas: () => this.areas,
    abilities: () => this.abilities
  },
  data() {
    return {
      equipments: [],
      areas: [],
      abilities: [],
      window: {
        width: 0,
        height: 0,
        top: 0,
        left: 0
      },
      oaToken: "",
      op,
      selectArea: "",
      select: {
        table_name: "",
        filter: [
          {
            key: "content",
            op: "like",
            value: ""
          },
          {
            key: "leibie",
            op: "eq",
            value: ""
          },
          {
            key: "start_time",
            op: "like",
            value: this.$moment().format('YYYY-MM-DD')
          },
          {
            key: "equipment_id",
            op: "in",
            value: []
          },
          {
            key: "is_adjust",
            op: "eq",
            value: -1
          }
        ],
        sort_name: 'start_time',
        page_size: 9999,
      },
      selectQuery: [],
      form: [],
      table: [],
      customForm: {
        customFormId: "",
        tableName: "",
      },


      resetTable: new Map([
        ["start_time",{
          formatter: (data, cell, val)=>{
            return val ? this.$moment(val).format("HH:mm") : ''
          }
        }],
        ["end_time",{
          formatter: (data, cell, val)=>{
            return val ? this.$moment(val).format("HH:mm") : ''
          }
        }],
        ["shichang",{
          formatter: (data) => {
            return this.$moment(data.end_time).diff(this.$moment(data.start_time),"hours",true) + "小时"
          },
          width: 120
        }]
      ])
    };
  },
  methods: {
    btnCondition ({ row }, item, index) {
      if (row.status === 0) {
        if (item === 'oa') {
          return false
        }
      }
      if ([2,3,4,5,6,7].find(i => i === row.status)) {
        if (item === 'delete' || item === 'oa') {
          return false
        }
      }
      if ([3,4,5,6,7].find(i => i === row.status)) {
        if (item === 'edit') {
          return false
        }
      }
      if (row.liuchengzhuangtai === 2 || row.liuchengzhuangtai === 3) {
        if (item === 'delete' || item === 'edit') {
          return false
        }
      }
      return true
    },

    objectSpanMethod({ row, column, rowIndex, columnIndex }) {
      const span = column["property"] + "-span";
      if (row[span]) {
        return row[span];
      }
    },

    mergeData(list) {
      return mergeTableRow({
        data: this.selectArea ? list.filter(i => (i.equipment_id_equipments_id_relation?.area === this.selectArea)) : list,
        mergeColNames: ["equipment_id_equipments_id_relation.area","equipment_id_equipments_id_relation.name"], // 需要合并的列，默认合并列相同的数据
        firstMergeColNames: ["equipment_id_equipments_id_relation.area","equipment_id_equipments_id_relation.name"], // 受影响的列，只合并以firstMerge为首的同类型数据
        firstMerge: "equipment_id", // 以哪列为基础进行合并，一般为第一列
      });
    },

    pickNoDistribute () {
      this.$refs['xyTable'].getListData()?.forEach(item => {
        if (item.status === 1) {
          this.$refs['xyTable'].toggleRowSelection(item)
        }
      })
    },

    async getEquipments () {
      const res = (await index({
        table_name: 'equipments',
        page: 1,
        page_size: 9999
      },false))?.data || []
      this.equipments = this.areas.map(i => ({
        id: `area_${i.value}`,
        name: i.key,
        children: res.filter(j => j.area === i.value)
      }))

      this.$nextTick(() => {
        this.areas.forEach(i => {
          this.$refs['elTree'].setChecked(`area_${i.value}`, true, true)
        })
      })
    },

    async getArea() {
      const obj = (await formFieldShow({ id: 4 }, false))?.select_item;
      if (obj && typeof obj === "object") {
        let keys = Object.keys(obj);
        if (keys.length > 0) {
          this.areas = keys.map((key) => {
            return {
              key,
              value: /^\d*$/.test(obj[key]) ? Number(obj[key]) : obj[key],
            };
          });
        }
      }
      this.$bus.$emit("areas", this.areas);
      await this.getEquipments()
    },
    async getAbility() {
      const obj = (await formFieldShow({ id: 31 }, false))?.select_item;
      if (obj && typeof obj === "object") {
        let keys = Object.keys(obj);
        if (keys.length > 0) {
          this.abilities = keys.map((key) => {
            return {
              key,
              value: /^\d*$/.test(obj[key]) ? Number(obj[key]) : obj[key],
            };
          });
        }
      }
      this.$bus.$emit("yinpaishui", this.abilities);
    },

    async toOa (row) {
      if (!this.oaToken) {
        this.oaToken = (await getOaToken()).oatoken
      }
      let jsonInfo = {
        'title': row.equipment_id_equipments_id_relation?.name,
        '65aa1a59e408c': row.start_time,
        '65aa1a7e4109d': row.level,
        '65aa1a442705f': row.content
      }
      let url =
        `${process.env.VUE_APP_OA_URL}/admin/flow/create/34?diaoling_oatoken=${this.oaToken}&out_diaoling_id=${row.id}&default_json=${JSON.stringify(jsonInfo)}`
      window.open(url, 'diaoling',
        `top=${this.window.top},left=${this.window.left},width=${this.window.width},height=${this.window.height},location=0`
      )
    },

    async distributeTransfers () {
      let promiseAll = this.$refs['xyTable'].getSelection().map(i => {
        for (let key in i) {
          if (/_relation/g.test(key)) {
            delete i[key]
          }
        }
        i.status = 2;
        return save({
          table_name: 'transfers',
          ...i
        })
      })
      const res = await Promise.all(promiseAll)
      this.$message({
        type: 'success',
        message: `下发${res.length}条调令`
      })
      this.$refs['xyTable'].getTableData()
    },

    cloneTransfer () {
      this.$router.push({
        name: 'menu_14',
        params: {
          cloneTransfer: this.$refs['xyTable'].getSelection().map(i => ({
            equipment_id: i.equipment_id,
            start_time: this.$moment(i.start_time).format('HH:mm'),
            end_time: this.$moment(i.end_time).format('HH:mm'),
            content: i.content,
            level: i.level,
            kaiqishuliang: i.kaiqishuliang
          }))
        }
      })
    },

    handleCheckChange (data, checked, indeterminate) {
      this.treeValue = this.$refs['elTree'].getCheckedNodes(true)?.filter(i => !i.children)?.map(i => i.name).toString()
      this.select.filter[3].value = this.$refs['elTree'].getCheckedNodes(true)?.filter(i => !i.children)?.map(i => i.id)

      this.$refs['xyTable'].getTableData(true)
    },

    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 (
                    <img
                      style="height: 40px;"
                      alt={row[link_with_name]?.original_name}
                      src={row[link_with_name]?.url}
                    >
                    </img>
                  );
                } 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) => (
                        <img alt={o.original_name} src={o?.url}></img>
                      ))}
                    </div>
                  );
                } else {
                  return (
                    <div>
                      {row[link_with_name]?.map((o) => (
                        <p>
                          {o?.name ||
                            o?.no ||
                            o?.value ||
                            o?.biaoti ||
                            o?.mingcheng}
                        </p>
                      ))}
                    </div>
                  );
                }
              };
            }
          }

          let alignLeft = [];
          if (this.resetTable.get(i.field)) {
            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.resetTable.get(i.field)
            ))
            return
          }
          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({
        width: 100,
        label: "范围",
        prop: "equipment_id_equipments_id_relation.area",
        formatter:(data,row,val) => {
          return this.areas.find(i => i.value === val)?.key
        }
      });
      this.table.unshift({
        type: "index",
        width: 60,
        label: "序号",
        prop: "index"
      });
      this.table.unshift({
        label: "选择",
        prop: "selections",
        type: "selection",
        width: 46,
        reserveSelection: true
      })
      this.table.unshift({
        prop: "expand",
        type: "expand",
        width: 46,
        expandFn:({ row }) => {
          return (
            <div style="max-width: 600px;padding: 10px;">
              {
                (row.id_transfers_to_transfer_id_relation || []).map((i,index) => (
                  <div style="display: flex;">
                    <div style="font-weight: 600;padding: 0 10px;">{index+1}.</div>
                    <div>
                      <span style="font-weight: 600;padding: 0 6px;">调整时间：</span>
                      <span>{ this.$moment(i.created_at).format('YYYY-MM-DD HH:mm') }</span>
                    </div>
                    <div>
                      <span style="font-weight: 600;padding: 0 6px;">调整类型：</span>
                      <span>{ this.form.find(i => i.field === "tiaozhengleixing")?._params?.find(j => j.value == i.tiaozhengleixing)?.key }</span>
                    </div>
                    <div>
                      <span style="font-weight: 600;padding: 0 6px;">调整内容：</span>
                      <span>{ i.content }</span>
                    </div>
                  </div>
                ))
              }
            </div>
          )
        }
      })
    },
  },

  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,
      };
    },

    treeHeight () {
      return (this.$refs['xyTable']?.tableHeight + 36 || 630) + 'px'
    },
  },
  created() {
    this.window.width = screen.availWidth * 0.95
    this.window.height = screen.availHeight * 0.95
    this.window.top = (window.screen.height - 30 - this.window.height) / 2
    this.window.left = (window.screen.width - 10 - this.window.width) / 2

    this.getFormDetail();
    this.getArea();
    this.getAbility();
  },
};
</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>
