<template>
  <div class="ele-body">
    <el-card
      class="card_box"
      :body-style="{
        display: 'flex',
        flexDirection: 'column',
        alignItems: 'flex-start'
      }"
      shadow="never"
    >
      <ele-split-layout
        width="252px"
        allow-collapse
        :right-style="{ overflow: 'hidden' }"
      >
        <div class="ele-border-lighter split-layout-right-content">
          <!--    动态表单配置-->
          <div class="content-box">
            <div
              v-for="category in Object.keys(templateList)"
              :key="category"
              class="category_box"
            >
              <div class="category_box_title">{{
                getDictV('collaborative_type', category)
              }}</div>
              <div class="category_box_content">
                <div
                  v-for="v in templateList[category]"
                  :key="v.id"
                  class="category_content"
                  :title="v.name"
                  @click="handleStartProcess(v)"
                >
                  <svg-icon
                    style="width: 1.5em; height: 1.5em"
                    :icon-class="v.icon"
                    className="svg-icon-set"
                  ></svg-icon>
                  <span>
                    {{
                      v.name.length > 3
                        ? v.name[0] + v.name[1] + v.name[2] + '...'
                        : v.name
                    }}
                  </span>
                </div>
              </div>
            </div>
          </div>
        </div>
        <!-- 表格 -->
        <template v-slot:content>
          <div class="tab-box el-form-box">
            <el-tabs @tab-click="tabClick" v-model="activeName">
              <el-tab-pane
                v-for="tab in tabOptions"
                :key="tab.name"
                :label="tab.label"
                :name="tab.name"
                v-if="!tab.permission || $hasPermission(tab.permission)"
              >
              </el-tab-pane>
            </el-tabs>
            <!-- 共用查询条件（采用"全部记录"的查询项） -->
            <div class="filter-container">
              <el-form
                class="ele-form-search"
                @keyup.enter.native="handleSearch"
                @submit.native.prevent
              >
                <el-row :gutter="15" style="display: flex; align-items: center">
                  <el-col v-bind="{ span: 4 }">
                    <el-form-item
                      label="关键字："
                      prop="keyword"
                      label-width="70px"
                    >
                      <el-input placeholder="请输入" v-model="params.keyword"></el-input>
                    </el-form-item>
                  </el-col>
                  <el-col v-bind="{ span: 4 }">
                    <el-form-item label="分类：" label-width="60px">
                      <el-select
                        v-model="params.dictType"
                        @change="changeDictTypeChange"
                        clearable
                      >
                        <el-option
                          v-for="(item, index) in dictList[
                            'collaborative_type'
                          ]"
                          :key="index"
                          :value="item.value"
                          :label="item.label"
                        ></el-option>
                      </el-select>
                    </el-form-item>
                  </el-col>
                  <el-col v-bind="{ span: 4 }">
                    <el-form-item label="单据：" label-width="60px">
                      <el-select
                        v-model="params.formId"
                        @change="changeFormIdChange"
                        clearable
                      >
                        <el-option
                          v-for="(item, index) in templateList[params.dictType]"
                          :key="index"
                          :value="item.id"
                          :label="item.name"
                        ></el-option>
                      </el-select>
                    </el-form-item>
                  </el-col>
                  <el-col v-bind="{ span: 4 }">
                    <el-form-item
                      label="结果："
                      prop="result"
                      label-width="60px"
                    >
                      <DictSelection
                        dictName="流程实例的结果"
                        clearable
                        v-model="params.result"
                      >
                      </DictSelection>
                    </el-form-item>
                  </el-col>
                  <el-col v-bind="{ span: 4 }">
                    <el-form-item
                      label="发起人："
                      prop="startUserName"
                      label-width="70px"
                    >
                      <el-input
                        v-model="params.startUserName"
                        clearable
                      ></el-input>
                    </el-form-item>
                  </el-col>
                  <el-col v-bind="{ span: 6 }">
                    <el-form-item
                      label="创建时间："
                      prop="createTime1"
                      label-width="90px"
                    >
                      <el-date-picker
                        v-model="createTime1"
                        style="width: 100%"
                        value-format="yyyy-MM-dd HH:mm:ss"
                        type="daterange"
                        clearable
                        range-separator="-"
                        start-placeholder="开始日期"
                        end-placeholder="结束日期"
                        :default-time="['00:00:00', '23:59:59']"
                      />
                    </el-form-item>
                  </el-col>
                  <el-col v-bind="{ span: 4 }">
                    <el-form-item
                      label=""
                      prop="createTime1"
                      label-width="90px"
                    >
                      <div class="ele-form-actions">
                        <el-button
                          type="primary"
                          icon="el-icon-search"
                          class="ele-btn-icon"
                          @click="handleSearch"
                        >
                          查询
                        </el-button>
                        <el-button @click="handleReset">重置</el-button>
                      </div>
                    </el-form-item>
                  </el-col>
                </el-row>
              </el-form>
            </div>
            <!-- 共用表格 -->
            <ele-pro-table
              ref="table"
              height="calc(100vh - 450px)"
              :columns="columns"
              :datasource="datasource"
              :init-load="false"
              :cache-key="cacheKeyUrl"
              :page-size="20"
              :selection.sync="selection"
              @columns-change="handleColumnChange"
            >
              <!-- 表头工具栏 -->
              <template v-slot:toolbar>
                <el-button
                  type="primary"
                  class="el-icon-printer"
                  size="small"
                  @click="handlePrint"
                >
                  打印
                </el-button>
              </template>
              <template v-slot:formName="{ row }">
                <el-link
                  type="primary"
                  :underline="false"
                  @click="handleDetail(row)"
                >
                  {{ row.formName }}
                </el-link>
              </template>
              <template v-slot:result="{ row }">
                <el-tag
                  size="medium"
                  :type="
                    getTimelineItemType(
                      getDictValue('流程实例的结果', row.result)
                    )
                  "
                >
                  {{ getDictValue('流程实例的结果', row.result) }}
                </el-tag>
              </template>
              <template v-slot:dictType="{ row }">
                {{ getDictV('collaborative_type', row.dictType) }}
              </template>
              <template v-slot:durationInMillis="{ row }">
                {{ getDateTime(row.durationInMillis) }}
              </template>
              <template v-slot:listName="{ row }">
                <el-link
                  type="primary"
                  :underline="false"
                  @click="handleDetail(row)"
                >
                  {{ row.listName }}
                </el-link>
              </template>
              <template v-slot:remark="{ row }">
                <div
                  style="
                    max-height: 180px;
                    overflow: hidden;
                    padding: 5px;
                    overflow-y: auto;
                  "
                >
                  <template
                    v-if="row?.formJson?.makingJson"
                    v-for="(item, index) in JSON.parse(
                      row?.formJson?.makingJson
                    )?.list.filter(
                      (val) =>
                        ![
                          'grid',
                          'blank',
                          'report',
                          'component',
                          'card',
                          'collapse',
                          'tabs',
                          'inline',
                          'divider',
                          'alert',
                          'table',
                          'subform',
                          'dialog'
                        ].includes(val.type)
                    )"
                  >
                    <div style="display: flex">
                      <div>{{ item.name }}：</div>
                      <div v-if="item.type == 'imgupload'">
                        <el-image
                          v-if="row[item.model].length"
                          style="width: 100px; height: 100px"
                          :src="row[item.model][0].url"
                          :preview-src-list="row[item.model].map((i) => i.url)"
                        >
                        </el-image>
                      </div>
                      <div v-else-if="item.type == 'fileupload'">
                        <fileMain
                          v-if="row[item.model]?.length"
                          type="view"
                          v-model="row[item.model]"
                        ></fileMain>
                      </div>

                      <div
                        v-else-if="
                          [
                            'deptCascader',
                            'deptAndUserCascader',
                            'userSelect'
                          ].includes(item.type)
                        "
                      >
                        <div
                          style="white-space: initial"
                          v-if="
                            item.options.remoteDataSource == 'getGroupUserTree'
                          "
                        >
                          {{ getDeptUserName(row[item.model]) }}
                        </div>
                        <div
                          style="white-space: initial"
                          v-else-if="
                            item.options.remoteDataSource == 'getUserPage'
                          "
                        >
                          {{ getUserName(row[item.model]) }}
                        </div>
                        <div style="white-space: initial" v-else>
                          {{ getDeptName(row[item.model]) }}</div
                        >
                      </div>

                      <div v-else>
                        {{ formatValue(row[item.model]) }}
                      </div>
                    </div>
                  </template>
                </div>
              </template>
            </ele-pro-table>
          </div>
        </template>
      </ele-split-layout>
    </el-card>
    <process-submit-dialog
      :process-submit-dialog-flag.sync="processSubmitDialogFlag"
      v-if="processSubmitDialogFlag"
      ref="processSubmitDialogRef"
      @reload="reload"
    ></process-submit-dialog>

    <detail ref="detailRef"></detail>
    <formDetail
      v-if="formDetailDialogFlag"
      :view="true"
      ref="formDetailDialogRef"
      :form-detail-dialog-flag.sync="formDetailDialogFlag"
    ></formDetail>
    <!-- 隐藏的打印服务实例：复用 detail 的 printRows 批量打印 -->
    <formDetail ref="printService" v-show="false"></formDetail>
  </div>
</template>
<script>
  import {
    getBpmCustomFormList,
    getProcessInstanceDeptPage,
    getProcessInstanceNoticePage,
    getProcessInstancePage,
    getProcessInstanceAllPage
  } from '@/api/bpm/task';
  import { getDate } from '@/utils/dateUtils';
  import dictMixins from '@/mixins/dictMixins';
  import detail from '@/views/bpm/processInstance/detail.vue';
  import formDetail from './detail.vue';
  import { getByCode } from '@/api/system/dictionary-data';
  import { getFile } from '@/api/system/file';
  import { getUserPage } from '@/api/tickets';
  import { listOrganizations } from '@/api/system/organization';
  import tabMixins from '@/mixins/tableColumnsMixin';
  import { getGroupUserTree } from '@/api/main';

  // 默认表单数据
  const defaultParams = {
    dictType: '',
    status: '',
    name: '',
    formId: '',
    keyword: ''
  };
  export default {
    name: 'index',
    components: {
      detail,
      formDetail
    },
    mixins: [dictMixins, tabMixins],
    data() {
      return {
        currentDictType: '',
        currentFormId: '',
        cacheKeyUrl: 'wt-202608101035-eaf1548b-collaborative',
        configFormDialogFlag: false,
        processSubmitDialogFlag: false,
        formDetailDialogFlag: false,
        templateList: {},
        dictList: {},
        defaultTemplateList: [],
        userList: [],
        deptList: [],
        groupUserTree: [],
        params: { ...defaultParams },
        statusList: [],
        formColumnList: [],
        createTime1: [],
        selection: [],
        // 个人 / 部门 / 通知我的
        activeName: 'user',
        tabOptions: [
          {
            label: '个人记录',
            name: 'user'
          },
          {
            label: '部门记录',
            name: 'dept',
            permission: 'wt:collaborative:department'
          },
          {
            label: '通知我的记录',
            name: 'notice'
          },
          {
            label: '全部记录',
            name: 'all',
            permission: 'wt:collaborative:all'
          }
        ],
        // 当前 tab 对应的接口方法映射
        apiMap: {
          user: 'getProcessInstancePage',
          dept: 'getProcessInstanceDeptPage',
          notice: 'getProcessInstanceNoticePage',
          all: 'getProcessInstanceAllPage'
        }
      };
    },
    computed: {
      // 是否开启响应式布局
      styleResponsive() {
        return this.$store.state.theme.styleResponsive;
      },
      columns() {
        return [
          {
            width: 45,
            type: 'selection',
            columnKey: 'selection',
            align: 'center'
          },
          {
            columnKey: 'index',
            label: '序号',
            type: 'index',
            width: 55,
            align: 'center',
            showOverflowTooltip: true,
            fixed: 'left'
          },
          {
            prop: 'dictType',
            label: '分类',
            align: 'center',
            slot: 'dictType',
            showOverflowTooltip: true,
            width: 80
          },
          {
            prop: 'formName',
            label: '单据',
            align: 'center',
            slot: 'formName',
            showOverflowTooltip: true,
            minWidth: 120
          },
          {
            prop: 'remark',
            label: '摘要',
            align: 'center',
            slot: 'remark',
            minWidth: 300
          },
          {
            prop: 'listName',
            label: '名称',
            align: 'center',
            slot: 'listName',
            showOverflowTooltip: true,
            minWidth: 120
          },
          {
            prop: 'startUserName',
            label: '发起人',
            align: 'center',
            showOverflowTooltip: true,
            width: 120
          },
          // ...list,
          {
            prop: 'result',
            slot: 'result',
            label: '结果',
            align: 'center',
            showOverflowTooltip: true,
            width: 80
          },
          {
            prop: 'endTime',
            label: '审批时间',
            align: 'center',
            showOverflowTooltip: true,
            width: 160
          },
          {
            prop: 'createTime',
            label: '创建时间',
            align: 'center',
            showOverflowTooltip: true,
            width: 160
          }
        ];
      },

      getUserName() {
        return (id) => {
          if (!id) return '';
          let find = this.userList.find((item) => item.id == id) || {};
          return find.name;
        };
      },

      getDeptUserName() {
        return (id = []) => {
          if (!id.length) return '';
          return id
            .map((pathArr) => {
              const names = this.getNodeNamesByPath(
                this.groupUserTree,
                pathArr
              );
              return names.join('/');
            })
            .join(',');
        };
      },
      getDeptName() {
        return (id = []) => {
          if (!id.length) return '';

          id = Array.isArray(id) ? id : [id];
          let find =
            this.deptList.find((item) => item.id == id[id.length - 1]) || {};
          return find.name;
        };
      }
    },
    watch: {
      // currentFormId: {
      //   handler(val) {
      //     this.params.formId =  this.params.dictType ? this.templateList[val][0].id : '';
      //     this.currentFormId = this.templateList[this.currentDictType][0].id;
      //     this.allReload();
      //     this.reload();
      //     this.deptReload();
      //     this.noticeReload();
      //   }
      // },
      // currentDictType: {
      //   handler(val) {
      //     this.params.formId =  this.templateList[val][0].id;
      //     this.currentFormId = this.templateList[val][0].id;
      //     this.allReload();
      //     this.reload();
      //     this.deptReload();
      //     this.noticeReload();
      //   }
      // }
    },
    async created() {
      await this.getDictList('collaborative_type');
      await this.getTemplateList();
      await this.getUserList();
      await this.getDeptList();
      await this.getGroupUserTree();
      // 默认进入页面显示个人记录并加载其数据
      this.activeName = 'user';
      this.handleSearch();
    },
    methods: {
      formatValue(value) {
        if (value === null || value === undefined) {
          return ''; // 空值处理
        }
        if (typeof value === 'object' && value !== null) {
          if ('id' in value && 'code' in value && 'name' in value) {
            return value.code;
          } else {
            return JSON.stringify(value, null, 2);
          }
        }
        return value;
      },
      getDictV(code, val) {
        if (!this.dictList[code]) return '';
        return this.dictList[code].find((item) => item.value == val)?.label;
      },
      async getDictList(code) {
        let { data: res } = await getByCode(code);
        this.dictList[code] = res.map((item) => {
          let values = Object.keys(item);
          return {
            value: values[0],
            label: item[values[0]]
          };
        });
      },
      //获取人员数据
      async getUserList() {
        let params = { pageNum: 1, size: -1 };
        let { list } = await getUserPage(params);
        this.userList = list;
      },
      //获取部门数据
      async getDeptList() {
        this.deptList = await listOrganizations();
      },
      async getGroupUserTree() {
        this.groupUserTree = await getGroupUserTree();
      },
      // 根据路径数组从树形结构中递归获取节点名称
      getNodeNamesByPath(tree, pathArr) {
        const names = [];
        let nodes = tree;
        for (const id of pathArr) {
          const node = nodes.find((item) => item.id == id);
          console.log(node, 'node');
          if (node) {
            if (node.type == '1') {
              names.push(node.name);
            }
            nodes = node.children || [];
          } else {
            break;
          }
        }
        return names;
      },
      getFiles(row = []) {
        row.forEach((item) => {
          getFile({ objectName: item.storePath }, item.name);
        });
      },
      async getTemplateList() {
        this.defaultTemplateList = await getBpmCustomFormList({ status: 1 });
        this.templateList = _.groupBy(this.defaultTemplateList, 'dictType');
        // this.params.dictType = this.dictList['collaborative_type'][0].value;
        this.currentDictType = this.dictList['collaborative_type'][0].value;
        this.currentFormId = this.templateList[this.currentDictType][0]?.id;
        // this.params.formId = this.templateList[this.currentDictType][0]?.id;
        let makingJson =
          JSON.parse(this.defaultTemplateList?.[0]?.formJson?.makingJson) || {};
        console.log('makingJson~~~', makingJson);
        // this.formColumnList = makingJson.list;
        console.log(
          // this.formColumnList,
          this.templateList[this.currentDictType]
        );
      },
      handleStartProcess(i) {
        this.processSubmitDialogFlag = true;
        this.$nextTick(() => {
          this.$refs.processSubmitDialogRef.init(i);
        });
      },
      /* 表格数据源：根据当前 tab 切换不同接口 */
      async datasource({ page, limit, where, order }) {
        let [createTimeBegin, createTimeEnd] = this.createTime1 || [];
        let apiName = this.apiMap[this.activeName] || 'getProcessInstancePage';
        let data = await this.callApi(
          apiName,
          page,
          limit,
          createTimeBegin,
          createTimeEnd
        );

        console.log(data.list, 'data~~~');
        return {
          count: data.count,
          list: data.list.map((item) => {
            return {
              ...item,
              listName: item.name,
              ...item.valueJson
            };
          })
        };
      },
      // 调用对应接口
      async callApi(apiName, page, limit, createTimeBegin, createTimeEnd) {
        const apiMap = {
          getProcessInstancePage,
          getProcessInstanceDeptPage,
          getProcessInstanceNoticePage,
          getProcessInstanceAllPage
        };
        return await apiMap[apiName]({
          pageNo: page,
          pageSize: limit,
          ...this.params,
          processType: '1',
          createTimeBegin,
          createTimeEnd
        });
      },
      /* 刷新表格：根据当前选中的 tab 刷新 */
      handleSearch(where) {
        let find =
          this.defaultTemplateList.find(
            (item) => item.id == this.currentFormId
          ) || {};
        let makingJson = find.formJson?.makingJson
          ? JSON.parse(find.formJson.makingJson) || {}
          : {};
        console.log(makingJson, 'makingJson');
        // this.formColumnList = makingJson.list;
        this.$nextTick(() => {
          this.$refs.table.reload({ page: 1, where });
        });
      },
      /* 重置 */
      handleReset() {
        this.params = { ...defaultParams };
        this.createTime1 = [];
        // this.params.dictType = '';
        // this.params.formId = '';
        // this.currentDictType = this.dictList['collaborative_type'][0].value;
        // this.currentFormId = this.templateList[this.currentDictType][0]?.id;
        this.handleSearch();
      },
      /* 勾选记录批量打印：复用 detail 组件的 printRows */
      handlePrint() {
        if (!this.selection || this.selection.length === 0) {
          this.$message.warning('请先勾选需要打印的记录');
          return;
        }
        if (!this.$refs.printService) {
          this.$message.error('打印组件未就绪');
          return;
        }
        this.$refs.printService.printRows(this.selection);
      },
      /**  */
      handleAudit(row) {
        this.$refs.detailRef.open(row.id);
      },
      /**  */
      handleDetail(row) {
        this.formDetailDialogFlag = true;
        this.$nextTick(() => {
          this.$refs.formDetailDialogRef.open(row);
        });
      },
      getTimelineItemType(result) {
        if (result === '通过') {
          return 'success';
        }
        if (result === '不通过') {
          return 'danger';
        }
        if (result === '取消') {
          return 'info';
        }
        if (result === '处理中') {
          return 'warning';
        }

        return '';
      },
      getDateTime(ms) {
        return getDate(ms);
      },
      tabClick() {
        // 切换 tab 时按当前 tab 查询条件重新加载
        // this.handleSearch();
        this.handleReset();
      },
      changeDictTypeChange(v) {
        // this.currentDictType = v;
        this.params.formId = '';
        // this.currentFormId = this.templateList[v][0]?.id;
        this.handleSearch();
      },
      changeFormIdChange(v) {
        // this.currentFormId = v;
        this.handleSearch();
      }
    }
  };
</script>
<style scoped lang="scss">
  .ele-body {
    padding: 15px;
  }

  .ele-split-panel {
    width: 100%;
  }

  .filter-container {
    margin-bottom: 10px;
    margin-top: 10px;
  }

  .content-box {
    width: 100%;
    //max-width: 273px;
    //min-width: 90px;
    // margin-right: 10px;
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    //justify-content: space-between;

    .category_box {
      border-left: 1px solid #e1e1e1;
      border-bottom: 1px solid #e1e1e1;
      border-radius: 1px;
      // flex: 1 0 25%;
      margin-top: 5px;
      overflow: auto;
      width: 100%;

      .category_box_title {
        font-size: 14px;
        font-weight: bold;
        color: #fff8f8;
        height: 39px;
        display: flex;
        padding: 5px 20px;
        align-items: center;
        background: #1890ffd6;
        border-bottom: 1px solid #e1e1e1;
      }

      .category_box_content {
        display: flex;
        flex-direction: row;
        flex-wrap: wrap;
        // height: 60px;
        overflow: auto;

        .category_content {
          min-width: 33%;
          min-height: 60px;
          //flex: 1 1 0;
          display: flex;
          flex-direction: column;
          border-right: 1px solid #e1e1e1;
          border-bottom: 1px solid #e1e1e1;
          align-items: center;
          justify-content: center;
          //  font-weight: bold;

          &:nth-child(n) {
            span:nth-child(1) {
              transform: scale(2);
            }

            span:nth-child(2) {
              padding-top: 5px;
            }
          }
        }

        .category_content:hover {
          cursor: pointer;
          background-color: rgba(135, 181, 243, 0.29);
        }
      }
    }

    .category_box:last-child {
      border-right: 1px solid #e1e1e1;
    }
  }

  .tab-box {
    // width: calc(100vw - 552px);
    //max-width: 1100px;
    //min-width: 600px;
    margin-top: 6px;
    height: 98%;

    .el-tabs--border-card {
      height: 100%;
    }
  }

  ::v-deep .card_box {
    .el-card__body {
      padding: 10px;
      height: 86vh;
    }
  }

  ::v-deep .ele-table-tool {
    display: flex;
    flex-direction: row;
    flex-wrap: nowrap !important;
  }
</style>
