<template>
  <div
    :class="isMobile ? 'isMobile' : 'isPC'"
    :style="{
      '--titleContent': titleContent,
    }"
  >
    <div ref="titleContent" style="padding-bottom: 10px" class="title">
      <template v-if="!isMobile">
        <span v-if="instId && isSub">流程编号:{{ instId }}</span>
        <div class="title-group">
          <div class="btn-group">
            <div v-for="item in btnList" :key="item.id" class="btn-item">
              <span class="icon" :style="{ background: item.bgColor }"></span>
              <span class="label">{{ item.label }}</span>
            </div>
          </div>
          <div>
            <div class="title-right">
              <el-button
                class="title-right-icon-out"
                icon="el-icon-zoom-out"
                :disabled="scaleSize <= 50"
                @click="onChangeSize('Small')"
              ></el-button>
              <div class="title-right-content">{{ scaleSize }}%</div>
              <el-button
                class="title-right-icon-in"
                icon="el-icon-zoom-in"
                :disabled="scaleSize >= 300"
                @click="onChangeSize('Big')"
              ></el-button>
            </div>
          </div>
        </div>
      </template>
      <template v-else>
        <van-collapse v-model="activeNames" @change="onChangeCollapse">
          <van-collapse-item title="流程状态" name="1" class="isMobile_title">
            <div class="btn-group">
              <div v-for="item in btnList" :key="item.id" class="btn-item">
                <span class="icon" :style="{ background: item.bgColor }"></span>
                <span class="label">{{ item.label }}</span>
              </div>
            </div>
          </van-collapse-item>
        </van-collapse>
      </template>
    </div>
    <!-- v-touch:panup="vue2action"
      v-touch:pandown="vuepandown" -->
    <div
      v-if="isMobile"
      class="title-right"
      :class="[
        activeNames.length > 0
          ? 'title-right-hasActiveNames'
          : 'title-right-noActiveNames',
      ]"
    >
      <el-button
        class="title-right-icon-out"
        icon="el-icon-zoom-out"
        :disabled="scaleSize <= 50"
        @click="onChangeSize('Small')"
      ></el-button>
      <div class="title-right-content">{{ scaleSize }}%</div>
      <el-button
        class="title-right-icon-in"
        icon="el-icon-zoom-in"
        :disabled="scaleSize >= 300"
        @click="onChangeSize('Big')"
      ></el-button>
    </div>
    <div
      ref="scrollContent"
      class="flow-chart"
      :style="{
        '--imgWidth': imgWidth + 50 + 'px',
        '--imgHeight': imgHeight + 50 + 'px',
        '--scaleSize': scaleSize / 100,
      }"
      :class="[
        isMobile ? 'flow-chart_sty' : 'flow-chart-noMobile',
        activeNames.length > 0 ? 'addimgHeight' : 'addHeight',
      ]"
    >
      <div
        ref="contents"
        :style="{
          position: 'relative',
          width: imgWidth + 'px',
          height: imgHeight + 'px',
          background: 'url(' + backGroundImg + ') no-repeat',
        }"
      >
        <template v-for="(layout, key) in listLayout">
          <template v-if="isMobile">
            <i
              v-if="isShowTop(layout)"
              :key="key"
              slot="reference"
              class="node-tip_i"
              :style="getStyle(layout)"
              @click="openSubFlow(layout)"
            >
              <template v-if="['START', 'END'].includes(layout.nodeType)">
                <ht-icon
                  v-if="layout.nodeType === 'START'"
                  name="start"
                  class="node-type_icon images"
                  style="color: #50a284"
                />
                <ht-icon
                  v-if="layout.nodeType === 'END'"
                  name="ends"
                  class="node-type_icon images"
                  style="color: #ffae44"
                />
              </template>
              <template v-else>
                <!-- 节点顶部的图标和节点名称 -->
                <div
                  class="node-top_div"
                  :style="{
                    background: isArrived(layout)
                      ? nodeColorMap[layout.nodeId]
                      : '#E6E6E6',
                    width: layout.width + 'px',
                  }"
                >
                  <span
                    style="
                      display: inline-block;
                      margin-left: 8px;
                      margin-top: 4px;
                    "
                  >
                    <ht-icon
                      :name="layout.uniqueNodeType"
                      class="node-type_icon"
                      :fill="isArrived(layout) ? '#FFFFFF' : '#262626'"
                    />
                    <span
                      class="node-right_span"
                      :style="{
                        color: isArrived(layout) ? '#FFFFFF' : '#262626',
                        width: layout.width - 40 + 'px',
                      }"
                    >
                      {{ layout.name }}
                    </span>
                  </span>
                </div>

                <!-- 外部子流程 -->
                <div
                  v-if="layout.nodeType == 'CALLACTIVITY'"
                  class="node-auditor_name"
                  style="top: 50px"
                >
                  外部子流程
                  <span style="color: #0080fe; margin-left: 10px">
                    查看更多
                  </span>
                </div>

                <!-- 服务任务 -->
                <div
                  v-if="layout.nodeType == 'SERVICETASK'"
                  class="node-auditor_name"
                  style="top: 44px"
                >
                  <span
                    class="auditor_left_icon"
                    :style="{
                      background:
                        statusColorMap[
                          serviceStatusMap[getServiceStatus(layout)].status
                        ],
                      marginBottom: '3px',
                    }"
                  ></span>
                  <span
                    class="node-right_span"
                    :style="{
                      color:
                        statusColorMap[
                          serviceStatusMap[getServiceStatus(layout)].status
                        ],
                      marginLeft: '8px',
                    }"
                  >
                    {{ serviceStatusMap[getServiceStatus(layout)].statusVal }}
                  </span>
                </div>
                <!-- 用户任务(审批过) -->
                <div v-if="isUserTask(layout) && hasOpinion(layout)">
                  <div :style="getAuditorStyle(layout)">
                    <span
                      class="auditor_left_icon"
                      :style="{ background: nodeColorMap[layout.nodeId] }"
                    ></span>
                    <span style="margin-left: 8px">
                      {{ getLastOpnion(layout).statusVal }}
                    </span>
                  </div>
                  <div class="node-auditor_name" style="top: 50px">
                    <i class="icon-jiaose1 icon-font node-type_icon"></i>
                    <span
                      v-if="getLastOpnion(layout).auditorName"
                      class="node-right_span"
                      :style="{ width: layout.width - 40 + 'px' }"
                    >
                      {{ getLastOpnion(layout).auditorName }}
                    </span>
                    <span
                      v-else
                      class="node-right_span"
                      :style="{ width: layout.width - 40 + 'px' }"
                    >
                      {{
                        getQualfiedNames(getLastOpnion(layout).qualfieds).join(
                          '/'
                        )
                      }}
                    </span>
                  </div>
                </div>
                <!-- 用户任务(未审批过) -->
                <div
                  v-else-if="isUserTask(layout)"
                  class="node-auditor_name node-unapproved"
                  style="top: 44px"
                >
                  <i class="icon-jiaose1 icon-font"></i>

                  <!-- <ht-icon name="org" class="node-type_icon" scale="0.8" />
                  <span
                    class="node-right_span"
                    :style="{ width: layout.width - 40 + 'px' }"
                  >
                    未产生审批人
                  </span> -->
                </div>
              </template>
            </i>
          </template>
          <el-popover
            v-else
            :key="layout.nodeId"
            trigger="hover"
            placement="bottom-start"
            :disabled="instId && !isUserTask(layout)"
          >
            <div v-if="nodeOpinions[layout.nodeId]" class="options">
              <div class="title">审批详情({{ layout.name }})</div>
              <!-- 已审批/待审批节点 -->
              <template v-if="hasOpinion(layout)">
                <FlowChartNodeDetail
                  v-if="layout.nodeType != 'SIGNTASK'"
                  :opinions="getData(layout)"
                  :status-color-map="statusColorMap"
                  :layout-name="layout.name"
                />

                <el-collapse v-else v-model="activeMap[layout.nodeId]">
                  <el-collapse-item
                    v-for="(op, $index) in getSignGroup(layout)"
                    :key="$index"
                    :name="$index"
                  >
                    <template slot="title">
                      <p style="width: 100%">
                        <span>
                          第{{ getSignGroup(layout).length - $index }}次会签
                        </span>
                        <span
                          style="
                            display: inline-block;
                            float: right;
                            margin-right: 10px;
                          "
                        >
                          审批结果:
                          <span
                            :style="{
                              color: statusColorMap[
                                signStatusMap[op.allOpinionStatus].status
                              ]
                                ? statusColorMap[
                                    signStatusMap[op.allOpinionStatus].status
                                  ]
                                : '',
                            }"
                          >
                            {{ signStatusMap[op.allOpinionStatus].statusVal }}
                          </span>
                        </span>
                      </p>
                    </template>
                    <FlowChartNodeDetail
                      :opinions="op.sorterOpinion"
                      :status-color-map="statusColorMap"
                    />
                  </el-collapse-item>
                </el-collapse>
              </template>

              <!-- 未审批节点 -->
              <template v-else>
                <div class="sub-title">节点设置详情</div>
                <table>
                  <tr>
                    <td class="label">状态</td>
                    <td class="value">未产生过任务</td>
                  </tr>
                  <tr>
                    <td class="label">
                      <span>暂定候选人</span>
                      <el-tooltip
                        effect="light"
                        content="暂定的有审批资格的用户及用户组，实际候选人要在产生任务以后才能确定"
                        placement="right"
                      >
                        <i class="el-icon-question"></i>
                      </el-tooltip>
                    </td>
                    <td class="value">
                      <el-tooltip
                        v-if="
                          getUsers(layout).users &&
                          getUsers(layout).users.length
                        "
                        effect="light"
                        :content="getUsers(layout).users.replaceAll('/', '，')"
                        placement="top"
                      >
                        <div class="approval-name">
                          {{ getUsers(layout).users }}
                        </div>
                      </el-tooltip>
                      <div
                        v-if="
                          getUsers(layout).userGroup &&
                          getUsers(layout).userGroup.length
                        "
                        class="user-group-wrap"
                      >
                        <template v-for="user in getUsers(layout).userGroup">
                          <el-tooltip
                            v-if="user.users"
                            :key="user.id"
                            effect="light"
                            :content="user.users.replaceAll(',', '，')"
                            placement="top"
                          >
                            <el-button class="user-btn">
                              {{ user.name }}
                            </el-button>
                          </el-tooltip>
                        </template>
                      </div>
                    </td>
                  </tr>
                </table>
              </template>
            </div>

            <i
              v-if="isShowTop(layout)"
              slot="reference"
              class="node-tip_i"
              :style="getStyle(layout)"
              @click="openSubFlow(layout)"
            >
              <div v-if="['START', 'END'].includes(layout.nodeType)">
                <ht-icon
                  v-if="layout.nodeType === 'START'"
                  name="start"
                  class="node-type_icon images"
                  style="color: #50a284"
                  :width="layout.width"
                  :height="layout.height"
                />
                <ht-icon
                  v-if="layout.nodeType === 'END'"
                  name="ends"
                  class="node-type_icon images"
                  style="color: #ffae44"
                  :width="layout.width"
                  :height="layout.height"
                />
              </div>

              <!-- 节点顶部的图标和节点名称 -->
              <div
                v-else
                class="node-top_div"
                :style="{
                  background: isArrived(layout)
                    ? nodeColorMap[layout.nodeId]
                    : '#E6E6E6',
                  width: layout.width + 'px',
                }"
              >
                <span
                  style="
                    display: inline-block;
                    margin-left: 8px;
                    margin-top: 4px;
                  "
                >
                  <ht-icon
                    :name="layout.uniqueNodeType"
                    class="node-type_icon"
                    :fill="isArrived(layout) ? '#FFFFFF' : '#262626'"
                  />
                  <span
                    class="node-right_span"
                    :style="{
                      color: isArrived(layout) ? '#FFFFFF' : '#262626',
                      width: layout.width - 40 + 'px',
                    }"
                  >
                    {{ layout.name }}
                  </span>
                </span>
              </div>

              <!-- 外部子流程 -->
              <div
                v-if="layout.nodeType == 'CALLACTIVITY'"
                class="node-auditor_name"
                style="top: 50px"
              >
                外部子流程
                <span style="color: #0080fe; margin-left: 10px">查看更多</span>
              </div>

              <!-- 服务任务 -->
              <div
                v-if="layout.nodeType == 'SERVICETASK'"
                class="node-auditor_name"
                style="top: 44px"
              >
                <span
                  class="auditor_left_icon"
                  :style="{
                    background:
                      statusColorMap[
                        serviceStatusMap[getServiceStatus(layout)].status
                      ],
                    marginBottom: '3px',
                  }"
                ></span>
                <span
                  class="node-right_span"
                  :style="{
                    color:
                      statusColorMap[
                        serviceStatusMap[getServiceStatus(layout)].status
                      ],
                    marginLeft: '10px',
                  }"
                >
                  {{ serviceStatusMap[getServiceStatus(layout)].statusVal }}
                </span>
              </div>
              <!-- 用户任务(审批过) -->
              <div v-if="isUserTask(layout) && hasOpinion(layout)">
                <div :style="getAuditorStyle(layout)">
                  <span
                    class="auditor_left_icon"
                    :style="{ background: nodeColorMap[layout.nodeId] }"
                  ></span>
                  <span style="margin-left: 8px">
                    {{ getLastOpnion(layout).statusVal }}
                  </span>
                </div>
                <div class="node-auditor_name" style="top: 50px">
                  <i class="icon-jiaose1 icon-font node-type_icon"></i>
                  <span
                    v-if="getLastOpnion(layout).auditorName"
                    class="node-right_span"
                    :style="{ width: layout.width - 40 + 'px' }"
                  >
                    {{ getLastOpnion(layout).auditorName }}
                  </span>
                  <span
                    v-else
                    class="node-right_span"
                    :style="{ width: layout.width - 40 + 'px' }"
                  >
                    {{
                      getQualfiedNames(getLastOpnion(layout).qualfieds).join(
                        '/'
                      )
                    }}
                  </span>
                </div>
              </div>
              <!-- 用户任务(未审批过) -->
              <div
                v-else-if="isUserTask(layout)"
                class="node-auditor_name node-unapproved"
                style="top: 40px"
              >
                <i class="icon-jiaose1 icon-font"></i>
                <!-- <ht-icon name="org" class="node-type_icon" scale="0.8" />
                <span
                  class="node-right_span"
                  :style="{ width: layout.width - 40 + 'px' }"
                >
                  未产生审批人
                </span> -->
              </div>
            </i>
          </el-popover>
        </template>
      </div>
    </div>

    <SubFlowChart
      ref="subFlowChartL"
      :def-id="defId"
      :inst-id="instId"
      :bpmn-inst-id="bpmnInstId"
      :custom-class="customClass"
      :sub-flow-chart-l-name="subFlowChartLName"
      class="subFlowChartL"
    />

    <!-- 移动端 -->
    <div v-if="nodeOpinions[layoutItem.nodeId]" class="options">
      <!-- 已审批/待审批节点 -->
      <template v-if="hasOpinion(layoutItem)">
        <van-popup
          v-if="layoutItem.nodeType != 'SIGNTASK'"
          v-model="showoptions"
          round
          safe-area-inset-bottom
          position="bottom"
        >
          <van-nav-bar
            :title="layoutItem.name"
            left-text="关闭"
            class="popup_header_fixed"
            @click-left="showoptions = false"
          />
          <FlowChartNodeDetail
            ref="FlowChartNodeDetail"
            :opinions="getData(layoutItem)"
            :status-color-map="statusColorMap"
            :layout-name="layoutItem.name"
            :margin-class="true"
          />
        </van-popup>
        <van-popup
          v-else
          v-model="Hqshowoptions"
          round
          safe-area-inset-bottom
          position="bottom"
        >
          <van-nav-bar
            :title="layoutItem.name"
            left-text="关闭"
            class="popup_header_fixed"
            @click-left="Hqshowoptions = false"
          />
          <div
            v-for="(op, $index) in getSignGroup(layoutItem)"
            :key="$index"
            :name="$index"
            class="hqContent"
          >
            <p>
              <span>
                第{{ getSignGroup(layoutItem).length - $index }}次会签
              </span>
              <span
                style="display: inline-block; float: right; margin-right: 10px"
              >
                审批结果:
                <span
                  :style="{
                    color: statusColorMap[
                      signStatusMap[op.allOpinionStatus].status
                    ]
                      ? statusColorMap[
                          signStatusMap[op.allOpinionStatus].status
                        ]
                      : '',
                  }"
                >
                  {{ signStatusMap[op.allOpinionStatus].statusVal }}
                </span>
              </span>
            </p>

            <FlowChartNodeDetail
              :opinions="op.sorterOpinion"
              :status-color-map="statusColorMap"
            />
          </div>
        </van-popup>
      </template>
      <van-popup
        v-else
        v-model="showoptions"
        round
        safe-area-inset-bottom
        position="bottom"
      >
        <van-nav-bar
          :title="layoutItem.name"
          left-text="关闭"
          class="popup_header_fixed"
          @click-left="showoptions = false"
        />
        <div class="sign marginClass">
          <div>
            <div class="label">
              <span>暂定候选人</span>
            </div>
            <div
              v-if="getData(layoutItem)"
              class="value orderItem"
              @click="showAllPeople(layoutItem)"
            >
              <span v-for="(user, index) in getData(layoutItem)" :key="user.id">
                <!-- <span v-if="!user.users"> -->
                <template v-if="index < 3">
                  <span v-if="0 < index">,</span>
                  <span>
                    {{ user.name }}
                  </span>
                </template>
              </span>

              <van-icon
                v-if="
                  (getData(layoutItem) && getData(layoutItem).length > 3) ||
                  (getData(layoutItem) && showOrder(layoutItem))
                "
                name="arrow"
              />
            </div>
            <div v-else class="value befValue">未产生暂定候选人</div>
          </div>
          <div>
            <div class="label">开始时间</div>
            <div class="value befValue">未产生开始时间</div>
          </div>
          <div>
            <div class="label">结束时间</div>
            <div class="value befValue">未产生结束时间</div>
          </div>
          <div>
            <div class="label">审批用时</div>
            <div class="value befValue">未产生审批用时</div>
          </div>
          <div>
            <div class="label">状态</div>
            <div class="value befValue">未产生处理状态</div>
          </div>
          <div>
            <div class="label">审批意见</div>
            <div class="value befValue">未产生审批意见</div>
          </div>
        </div>
      </van-popup>
    </div>
    <!-- //显示组织人员 -->
    <peoplePopup ref="peoplePopup"></peoplePopup>
  </div>
</template>

<script>
  import { EasyScroller } from 'easyscroller'
  import SubFlowChart from './SubChart.vue'
  import peoplePopup from './peoplePopup.vue'
  import FlowChartNodeDetail from './NodeDetail.vue'
  import mobileMode from '@/mixins/mobileMode.js'
  import startImg from '../../../src/assets/start.svg'
  import endImg from '../../../src/assets/end.svg'
  import popupMode from '@/mixins/popupMode.js'
  const btnList = [
    { id: 1, label: '未开始', bgColor: '#E6E6E6' },
    { id: 2, label: '当前节点', bgColor: '#0080FE' },
    { id: 3, label: '已办节点', bgColor: '#07C160' },
    { id: 4, label: '驳回节点', bgColor: '#E55555' },
    { id: 5, label: '人工终止', bgColor: '#C1AD9A' },
    { id: 6, label: '挂起', bgColor: '#866AD6' },
  ]

  // 会签整个节点的审批状态
  const signStatusMap = {
    0: {
      statusVal: '驳回重走',
      status: 'reject',
      opStatus: ['reject', 'backToStart'],
    },
    1: { statusVal: '同意', status: 'agree', opStatus: ['agree'] },
    2: {
      statusVal: '审批中',
      status: 'awaiting_check',
      opStatus: ['awaiting_check'],
    },
    3: {
      statusVal: '驳回不重走',
      status: 'reject',
      opStatus: ['reject', 'backToStart'],
    },
    4: { statusVal: '被撤回', status: 'agree', opStatus: ['revoker'] },
  }

  // 服务任务的状态
  const serviceStatusMap = {
    '-1': { statusVal: '等待执行', status: 'toBeExecuted' },
    0: { statusVal: '执行失败', status: 'reject' },
    1: { statusVal: '执行成功', status: 'agree' },
  }

  export default {
    name: 'FlowChartMain',
    mixins: [mobileMode, popupMode('Hqshowoptions', 'showoptions')],
    props: {
      defId: {
        type: String,
        default: '',
      },
      instId: {
        type: String,
        default: '',
      },
      bpmnInstId: {
        type: String,
        default: '',
      },
      customClass: {
        type: String,
        default: '',
      },
      isSub: {
        type: Boolean,
        default: false,
      },
    },
    components: { SubFlowChart, FlowChartNodeDetail, peoplePopup },
    data() {
      return {
        titleContent: null,
        scaleSize: 100,
        endImg: endImg,
        startImg: startImg,
        btnList: btnList,
        signStatusMap: signStatusMap,
        serviceStatusMap: serviceStatusMap,
        showFlowChart: false,
        showoptions: false,
        Hqshowoptions: false,
        imgWidth: '',
        imgHeight: '',
        backGroundImg: '',
        listLayout: '',
        subFlowChartLName: '',
        nodeOpinions: [],
        nodeColorMap: {},
        statusColorMap: {},
        subNodeId: '',
        activeMap: {},
        activeNames: [],
        layoutItem: {},
      }
    },

    created() {
      this.handleOpen()
    },
    mounted() {
      // if (this.isMobile) {
      //   this.$nextTick(() => {
      //     const element = this.$refs.scrollContent
      //     new EasyScroller(element, {
      //       scrollingX: true,
      //       scrollingY: true,
      //       zooming: true,
      //       minZoom: 0.9,
      //       maxZoom: 1.3,
      //       zoomLevel: 1,
      //       bouncing: false,
      //     })
      //   })
      // }
      this.titleContent = this.$refs.titleContent.offsetHeight + 10 + 5 + 'px'
    },
    methods: {
      onChangeCollapse() {
        //10px 为margin-buttom 5px 安全高度

        setTimeout(() => {
          this.titleContent =
            this.$refs.titleContent.offsetHeight + 10 + 5 + 'px'
        }, 300)
      },
      onChangeSize(type) {
        switch (type) {
          case 'Big':
            this.scaleSize += 10
            break
          case 'Small':
            this.scaleSize -= 10
            break
          default:
            break
        }
      },
      vue2action(evenObject) {
        let scrollTop = this.$refs.scrollContent.scrollTop

        let a = Number(evenObject.distance).toFixed(0)

        this.$refs.scrollContent.scrollTo({
          top: scrollTop + a * 10,
          behavior: 'smooth',
        })
      },
      vuepandown(evenObject) {
        let scrollTop = this.$refs.scrollContent.scrollTop

        let a = Number(evenObject.distance).toFixed(0)

        this.$refs.scrollContent.scrollTo({
          top: scrollTop - a * 10,
          behavior: 'smooth',
        })
      },
      getServiceStatus(layout) {
        if (!this.nodeOpinions || !this.nodeOpinions[layout.nodeId]) {
          return '-1'
        }
        return this.nodeOpinions[layout.nodeId].serviceStatus
      },
      isArrived(layout) {
        if (!this.nodeColorMap) {
          return false
        }
        return this.nodeColorMap[layout.nodeId]
      },
      openSubFlow(layout) {
        if (layout.nodeType != 'CALLACTIVITY') {
          if (this.isMobile) {
            this.layoutItem = layout
            //  <!-- 已审批/待审批节点 -->
            if (this.hasOpinion(layout)) {
              if (layout.nodeType != 'SIGNTASK') {
                this.$nextTick(() => {
                  this.showoptions = true
                })
              } else {
                // 会签
                this.Hqshowoptions = true
              }
            } else {
              // 未审批
              this.showoptions = true
            }

            return
          }
          return
        }

        this.subFlowChartLName = layout.name
        this.$refs.subFlowChartL.handleOpen(layout.nodeId)
      },
      //显示全部人
      showAllPeople(dataList) {
        this.$refs.peoplePopup.showDialog(this.getData(dataList))
      },
      isShowTop(layout) {
        const taskNames = [
          'USERTASK',
          'SIGNTASK',
          'CUSTOMSIGNTASK',
          'CALLACTIVITY',
          'SERVICETASK',
          'START',
          'END',
        ]

        if (this.isMobile) {
          taskNames.push('START')
          taskNames.push('END')
        }
        return taskNames.includes(layout.nodeType)
      },
      isUserTask(layout) {
        const taskNames = ['USERTASK', 'SIGNTASK', 'CUSTOMSIGNTASK']
        return taskNames.includes(layout.nodeType)
      },
      getAuditorStyle(layout) {
        let styleObj = {
          position: 'absolute',
          top: '30px',
          fontSize: '12px',
          paddingLeft: '10px',
        }
        if (this.nodeColorMap[layout.nodeId]) {
          styleObj.color = this.nodeColorMap[layout.nodeId]
        }
        return styleObj
      },
      hasOpinion(layout) {
        return (
          this.nodeOpinions[layout.nodeId] &&
          this.nodeOpinions[layout.nodeId].hasOpinion
        )
      },

      getQualfiedNames(qualfieds) {
        if (!qualfieds) {
          return []
        }
        let names = []
        let auditors = qualfieds
        if (auditors.constructor == String) {
          auditors = JSON.parse(qualfieds)
        }
        for (let index = 0; index < auditors.length; index++) {
          const a = auditors[index]
          if (a.name) {
            names.push(a.name)
          }
        }
        return names
      },

      // 获取最近一次的审批状态在流程节点显示。普通的用户任务直接取data的第一条。会签任务，取groupNode的第一条里返回的allOpinionStatus作为审批状态
      getLastOpnion(layout) {
        if (
          !this.nodeOpinions[layout.nodeId].data ||
          this.nodeOpinions[layout.nodeId].data.length == 0
        ) {
          return null
        }
        if (layout.nodeType != 'SIGNTASK') {
          return this.nodeOpinions[layout.nodeId].data[0]
        }

        let opinionData = this.nodeOpinions[layout.nodeId].data[0]
        if (
          this.nodeOpinions[layout.nodeId].groupNode &&
          this.nodeOpinions[layout.nodeId].groupNode.length > 0
        ) {
          const lastSignData =
            this.nodeOpinions[layout.nodeId].groupNode[0].sorterOpinion
          const allOpinionStatus =
            this.nodeOpinions[layout.nodeId].groupNode[0].allOpinionStatus
          const signStatus = this.signStatusMap[allOpinionStatus]
          if (signStatus) {
            let auditors = []
            opinionData.status = signStatus.status
            opinionData.statusVal = signStatus.statusVal
            lastSignData.forEach((l) => {
              if (l.status == 'awaiting_check') {
                auditors.push(this.getQualfiedNames(l.qualfieds))
              } else if (signStatus.opStatus.indexOf(l.status) > -1) {
                auditors.push(l.auditorName)
              }
            })
            opinionData.auditorName = auditors.join('/')
          }
        }
        return opinionData
      },
      showOrder(layout) {
        let data =
          this.nodeOpinions[layout.nodeId] &&
          this.nodeOpinions[layout.nodeId].data

        return data.some((item) => {
          return item.type != 'user'
        })
      },
      getData(layout) {
        return (
          this.nodeOpinions[layout.nodeId] &&
          this.nodeOpinions[layout.nodeId].data
        )
      },
      getUsers(data) {
        const userData =
          this.nodeOpinions[data.nodeId] && this.nodeOpinions[data.nodeId].data
        let result = {}
        if (userData && userData.length) {
          result.users = userData
            .filter((item) => !item.users)
            .map((item) => item.name)
            .join('/')

          result.userGroup = userData.filter((item) => item.users)
        }
        return result
      },
      getSignGroup(layout) {
        return (
          this.nodeOpinions[layout.nodeId] &&
          this.nodeOpinions[layout.nodeId].groupNode
        )
      },
      getStyle(layout) {
        let styleObj = {
          position: 'absolute',
          top: layout.y + 'px',
          left: layout.x + 'px',
          width: layout.width + 'px',
          height: layout.height + 'px',
          border: 'none',
          background: 'none',
        }
        if (layout.nodeType != 'SERVICETASK' && this.instId) {
          styleObj.cursor = 'pointer'
        }
        return styleObj
      },
      handleOpen() {
        this.showFlowChart = true
        const data = {
          defId: this.defId,
          instId: this.instId,
          bpmnInstId: this.bpmnInstId,
        }

        if (!this.defId && !this.instId) {
          return
        }
        this.$requestConfig.instanceFlowImage(data, (instFlowInfo) => {
          const {
            defId,
            instanceId,
            bpmDefLayout,
            nodeColorMap,
            statusColorMap,
          } = instFlowInfo
          let myDefId = ''
          if (['', 'null', 'undefined'].includes(instanceId)) {
            myDefId = defId
          }
          this.nodeColorMap = nodeColorMap
          this.statusColorMap = statusColorMap
          this.$requestConfig.getBpmImage('', instanceId, myDefId, (res) => {
            this.imgWidth = bpmDefLayout.width
            this.imgHeight = bpmDefLayout.height
            this.backGroundImg = res

            bpmDefLayout.listLayout.forEach((item) => {
              const style = {
                position: 'absolute',
                left: item.x + 'px',
                top: item.y + 'px',
                width: item.width + 'px',
                height: item.height + 'px',
              }
              item.style = style
              if (item.nodeType == 'SIGNTASK') {
                this.activeMap[item.nodeId] = [0]
              }
            })
            this.listLayout = bpmDefLayout.listLayout

            const tempIds = []
            this.listLayout.forEach((layout) => {
              const { nodeId, nodeType } = layout
              if (['USERTASK', 'SIGNTASK'].includes(nodeType)) {
                tempIds.push(nodeId)
              }
            })

            let nodeIds = tempIds.join(',')
            const data = { instId: this.instId, nodeIds, isDerive: false }
            if (this.instId) {
              // 流程图初始化的时候，只查询已到达节点的审批人。未到节点不推演，以免影响加载速度
              this.getNodeOpinions(data)
            }
          })
        })
      },
      getNodeOpinions(params) {
        this.$requestConfig.getNodeOpinionsPreview(params, (options) => {
          // 收集没有审批意见的节点
          let notArrivedNodeIds = []
          if (options) {
            // 不知道为啥后台只有一条审批历史的时候。直接返回数据，没有用节点id作为key。所以此处特殊处理下
            if (params.nodeIds.split(',').length == 1 && options.data) {
              let newOptions = {}
              newOptions[params.nodeIds] = options
              options = newOptions
            }
            for (const key in options) {
              const { data, hasOpinion } = options[key]
              if (data && hasOpinion) {
                data.forEach((ele) => {
                  if (ele.qualfieds) {
                    ele.qualfieds = eval('(' + ele.qualfieds + ')')
                  }
                  if (ele.createTime) {
                    ele.createTime = ele.createTime
                      ? new Date(ele.createTime.replace(/\-/g, '/')).format(
                          'yyyy/MM/dd HH:mm:ss'
                        )
                      : ''
                  }
                  if (ele.completeTime) {
                    ele.completeTime = ele.completeTime
                      ? new Date(ele.completeTime.replace(/\-/g, '/')).format(
                          'yyyy/MM/dd HH:mm:ss'
                        )
                      : ''
                  }
                })
              } else {
                notArrivedNodeIds.push(key)
              }

              if (params.getDerive) {
                this.nodeOpinions[key] = options[key]
              }
            }
          }

          if (!params.getDerive) {
            this.nodeOpinions = options
          }
          // 有未到达节点。并且没有查询过未到达节点
          if (notArrivedNodeIds.length > 0 && !params.getDerive) {
            // 传参推演未达到节点的审批人
            params.isDerive = true
            params.getDerive = true
            params.nodeIds = notArrivedNodeIds.join(',')
            // 再请求一次，以便悬浮的时候展示
            this.getNodeOpinions(params)
          }
        })
      },
    },
  }
</script>

<style lang="scss" scoped>
  @import './flowChart.scss';
  .approval-name {
    width: 234px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    font-size: 14px;
    color: #262626;
  }
  .user-group-wrap {
    width: 234px;
    display: flex;
    flex-wrap: wrap;
    margin-bottom: -8px;

    .user-btn {
      border-color: #409eff;
      color: #409eff;
      border-radius: 4px;
      padding: 8px 14px;

      margin: 0 8px 8px 0 !important;
    }
  }

  .btn-group {
    display: flex;
    flex-wrap: wrap;

    .btn-item {
      display: flex;
      align-items: center;
      margin-right: 40px;
      .icon {
        display: inline-block;
        width: 16px;
        height: 16px;
        margin-right: 8px;
        border-radius: 4px;
      }
      .lable {
        color: #606266;
      }
    }
  }

  .auditor_left_icon {
    display: inline-block;
    width: 8px;
    height: 8px;
    margin-right: 5px;
    border-radius: 4px;
    margin-bottom: 1px;
  }

  .flow-chart {
    overflow: auto;
    min-height: 500px;
    margin: 30px 24px 24px;
    max-height: 550px;
  }
  .flow-chart-noMobile {
    & > div {
      transform: scale(var(--scaleSize));
      transform-origin: left top;
    }
  }
  //  .addimgHeight {
  //   height: calc(50vh - 160px) !important;
  //   padding-bottom: 160px !important;
  // }
  // .addHeight {
  //   height: calc(50vh - 100px) !important;
  //   padding-bottom: 100px;
  // }
  .flow-chart_sty {
    // height: var(--imgHeight);
    // width: var(--imgWidth);
    height: calc(100% - var(--titleContent)) !important;
    width: calc(100vw - 32px);
    margin: 0 16px !important;
    // display: flex;
    min-height: 300px;
    & > div {
      margin: auto;
      zoom: var(--scaleSize);
    }
    position: relative;
  }
  .title {
    padding: 0 12px;
    font-size: 14px;
    font-weight: bold;
    margin-bottom: 10px;
  }

  .title + div {
    padding: 0 12px !important;
  }
  .sub-title + table {
    margin: 0 12px !important;
  }
  .sub-title {
    font-size: 12px;
  }
  .options {
    max-height: 420px;
    overflow-y: auto;
    width: 370px;
    word-break: break-all;
    ::v-deep table {
      margin-bottom: 10px;
      font-size: 12px;
      border-spacing: 0;
      border-bottom: 1px solid #e7eaec;
      border-left: 1px solid #e7eaec;
      td {
        padding: 8px;
        line-height: 1.42857;
        border-top: 1px solid #e7eaec;
        border-right: 1px solid #e7eaec;
        vertical-align: middle;
      }
      .label {
        width: 80px;
        font-weight: bold;
      }
      .value {
        width: 250px;
      }
      .opinion {
        max-width: 250px;
        min-width: 250px;
        word-wrap: break-word;
        white-space: pre-line;
      }
    }
  }
  ::v-deep .start-btn__flow-chart {
    width: 60% !important;
    .flow-chart {
      min-height: unset;
    }
  }

  .flow-chart ::v-deep i:focus {
    outline-width: 0;
  }
  .node-type_icon {
    vertical-align: middle;
    position: absolute;
  }

  .node-top_div {
    height: 24px;
    border-top-left-radius: 8px;
    border-top-right-radius: 8px;
    margin-left: 0.5px;
  }

  .node-right_span {
    display: inline-block;
    margin-left: 24px;
    line-height: 100%;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    margin-top: 1px;
  }

  .auditor-name_span {
    display: inline-block;
    margin-left: 10px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .node-auditor_name {
    position: absolute;
    color: #262626;
    font-size: 12px;
    padding-left: 10px;
  }

  .node-tip_i:hover {
    opacity: 1;
  }

  .node-tip_i {
    font-style: normal;
  }

  .isMobile {
    height: 100%;
    overflow: hidden;
    position: relative;
    &_title {
      color: #262626;
      font-weight: 400;
      font-size: 14px;
    }
    .images {
      width: 100%;
      height: 100%;
    }
    .flow-chart {
      overflow: auto;
      height: calc(100% - 45px);
    }
    .btn-group {
      display: flex;
      justify-content: flex-start;
      align-items: center;
      margin-left: 0;
      & > div {
        width: 25%;
        margin: 0 0 15px;
      }
    }
    .hqContent {
      margin-top: 44px;
      p {
        height: 34px;
        line-height: 34px;
        background: #f8f8f8;
        padding: 0 6px 0 16px;

        margin-bottom: 0 !important
        ;
      }
    }
    .subFlowChartL {
      // .van-popup {
      //   height: 80% !important;
      // }
    }

    // .addimgHeight {
    //   height: calc(50vh - 160px) !important;
    //   padding-bottom: 160px !important;
    // }
    // .addHeight {
    //   height: calc(50vh - 100px) !important;
    //   padding-bottom: 100px;
    // }
    .title-right {
      position: absolute;
      right: 12px;

      z-index: 3;
      display: flex;
      justify-content: center;
      align-items: center;
      flex-direction: column-reverse;

      border-radius: 16px;

      height: 100px;
      margin-top: 8px;
      width: 36px;
      background-color: #fff;
      &-hasActiveNames {
        top: 112px;
      }
      &-noActiveNames {
        top: 30px;
      }
      @mixin icon {
        width: 36px;
        height: 36px;

        border: 1px solid #ebebeb;
        display: flex;
        justify-content: center;
        align-items: center;

        padding: 0;
        position: absolute;
        &:active,
        &:hover {
          color: #262626 !important;
          background-color: #fff !important;
        }
        ::v-deep {
          i {
            font-size: 17px;
            color: #262626;
          }
        }
      }
      &-icon-out {
        bottom: -1px;
        border-radius: 0px 0px 18px 18px;
        @include icon;
      }
      &-icon-in {
        top: -1px;
        border-radius: 18px 18px 0px 0px;
        @include icon;
      }
      &-content {
        width: 34px;
        line-height: 30px;
        border-left: 1px solid #ebebeb;
        border-right: 1px solid #ebebeb;
        text-align: center;
        color: #606266;
        font-size: 12px;
        font-weight: normal;
        // transform: scale(0.9);
      }
    }
  }
  .isPC {
    .title {
      padding: 0;
    }
    .title-group {
      display: flex;
      justify-content: space-between;
    }
    .title-right {
      display: flex;
      justify-content: center;
      align-items: center;
      @mixin icon {
        width: 32px;
        height: 32px;
        border: 1px solid #dcdee0;
        display: flex;
        justify-content: center;
      }
      &-icon-out {
        border-radius: 8px 0px 0px 8px !important;
        @include icon;
      }
      &-icon-in {
        border-radius: 0px 8px 8px 0px !important;
        @include icon;
      }
      &-content {
        width: 72px;
        line-height: 30px;
        border-top: 1px solid #dcdee0;
        border-bottom: 1px solid #dcdee0;
        cursor: no-drop;
        text-align: center;
        color: #606266;
        font-size: 14px;
        font-weight: normal;
      }
    }
  }

  .icon-font {
    font-size: 14px;
  }
  .node-unapproved {
    padding: 0;
    display: flex;
    justify-content: center;
    align-items: center;
    width: 150px;
    .icon-font {
      font-size: 16px;
    }
  }
</style>
