<template>
  <div class="newOperations">
    <!--    newOperations盒子开始-->
    <div class="left">
      <!-- 左边第一个是隔离点组件 第二个是车间组件-->
      <SeparationPoint
        v-show="this.activeName == 'second'"
        @selection-changed="handleSelectPoint"
        :points="points"
      ></SeparationPoint>
      <keep-alive>
        <WorkShop
          v-show="this.activeName == 'first' || this.activeName == 'third'"
          @product-line-selected="handleProductLineSelected"
          @work-shop-selected="handleWorkshopSelected"
          :jobProps="jobProps"
        ></WorkShop>
      </keep-alive>
    </div>
    <!-- 作业区域  -->
    <div class="lefttree">
      <el-card class="lefttree-card" v-if="this.showWorkEare == true">
        <b class="title">作业区域</b>
        <div class="head-container">
          <el-input
            v-model="workareaName"
            placeholder="请输入作业区域"
            clearable
            size="small"
            prefix-icon="el-icon-search"
            style="margin-bottom: 20px"
            @input="handleInputChange"
          />
        </div>
        <div class="head-container">
          <el-tree
            :data="deptOptions"
            :props="defaultProps"
            :expand-on-click-node="false"
            :filter-node-method="filterNode"
            ref="tree"
            node-key="id"
            default-expand-all
            @node-click="handleNodeClick"
            highlight-current
          />
        </div>
      </el-card>
      <!-- 收起 -->
      <el-tooltip
        class="item"
        effect="dark"
        content="收起作业区域内容"
        placement="top-start"
      >
        <el-button
          type="primary"
          icon="el-icon-s-fold"
          class="btnwork"
          v-if="this.showWorkEare == true"
          @click="openWorkEare"
        ></el-button>
      </el-tooltip>

      <!-- 打开 -->
      <el-tooltip
        class="item"
        effect="dark"
        content="展开作业区域内容"
        placement="top-start"
      >
        <el-button
          type="primary"
          icon="el-icon-s-unfold"
          class="btnwork"
          v-if="this.showWorkEare == false"
          @click="closeWorkEare"
        ></el-button>
      </el-tooltip>
    </div>
    <div class="right">
      <div class="right_top">
        <el-card class="box-card">
          <div slot="header" class="clearfix">
            <span style="font-size: 18px">{{ this.getTicketTitle }}</span>
            <span
              style="
                padding: 1px 10px 1px 15%;
                font-size: 22px;
                cursor: pointer;
              "
              type="text"
              @click="goBack"
              >×</span
            >
          </div>
          <div class="text item">
            <!-- 新增作业票信息-->
            <b class="title">基本信息</b>
            <el-form ref="form" :model="form" label-width="90px">
              <!--getVisibleSopSelect是vuex判断新增是自定义还是建SOP作业票 第二个是编辑的时候如果有sopId就渲染 -->

              <el-form-item
                label="选择SOP"
                prop="sop"
                v-if="this.getVisibleSopSelect && this.form.sopId !== null"
              >
                <el-select
                  :disabled="this.getSopLook"
                  v-model="form.sopId"
                  placeholder="请选择sop"
                  clearable
                  style="width: 100%"
                  @clear="handleClearSop"
                  @change="handleSelectSOP"
                >
                  <el-option
                    v-for="dict in this.sopOptions"
                    :key="dict.sopId"
                    :label="dict.sopName"
                    :value="dict.sopId"
                  />
                </el-select>
              </el-form-item>

              <el-form-item label="作业票名称" prop="ticketName">
                <el-input
                  :disabled="this.getSopLook"
                  v-model="form.ticketName"
                  placeholder="请输入作业票名称"
                  style="width: 100%"
                />
              </el-form-item>
              <el-row>
                <el-col :span="16">
                  <el-form-item label="作业票编号" prop="ticketCode">
                    <el-input
                      :disabled="this.getSopLook"
                      v-model="form.ticketCode"
                      placeholder="请输入作业票编号"
                      style="width: 100%"
                    />
                  </el-form-item>
                </el-col>
                <el-col :span="8">
                  <el-form-item label-width="80">
                    <el-switch
                      :disabled="this.getSopLook"
                      v-model="autoGenFlag"
                      active-color="#13ce66"
                      active-text="自动生成"
                      @change="handleAutoGenChange(autoGenFlag)"
                    >
                    </el-switch>
                  </el-form-item>
                </el-col>
              </el-row>

              <el-form-item label="作业票类型" prop="ticketType">
                <el-select
                  :disabled="this.getSopLook"
                  v-model="form.ticketType"
                  placeholder="请选择作业类型"
                  clearable
                  style="width: 100%"
                >
                  <el-option
                    v-for="dict in dict.type.ticket_type"
                    :key="dict.value"
                    :label="dict.label"
                    :value="dict.value"
                  />
                </el-select>
              </el-form-item>
              <el-form-item label="作业内容" prop="ticketContent">
                <el-input
                  :disabled="this.getSopLook"
                  type="textarea"
                  v-model="form.ticketContent"
                  :rows="2"
                ></el-input>
              </el-form-item>
            </el-form>

            <!-- 隔离点信息-->
            <b class="title">隔离点信息</b>
            <el-form ref="form" :model="form" label-width="90px">
              <!-- <el-form-item label="作业区域" prop="workline">
                <el-input
                  v-model="form.workline"
                  style="width: 100%"
                  disabled
                />
              </el-form-item> -->
              <div class="text item">
                <el-table
                  :data="tableData"
                  stripe
                  height="300"
                  style="width: 100%; overflow: -moz-scrollbars-none"
                  class="tabData"
                >
                  <el-table-column prop="pointName" label="隔离点" width="60">
                    <template slot-scope="scope">
                      <span style="color: #2a87ff">{{
                        scope.row.pointName
                      }}</span>
                    </template>
                  </el-table-column>
                  <el-table-column
                    prop="pointType"
                    label="隔离点类型"
                    width="85"
                  >
                    <template slot-scope="scope">
                      {{ scope.row.pointType }}
                    </template>
                  </el-table-column>
                  <el-table-column
                    prop="powerType"
                    label="危险能量类型"
                    width="100"
                  >
                    <template slot-scope="scope">
                      {{ scope.row.powerType }}
                    </template>
                  </el-table-column>
                  <el-table-column
                    prop="prePointId"
                    label="前置隔离点"

                  >
                    <template slot-scope="scope">
                      <el-select
                        size="mini"
                        v-model="scope.row.prePointId"
                        @change="prePointIdChange(scope.row)"
                        @visible-change="onDropdownVisibleChange(scope.row)"
                        disabled
                        clearable
                      >
                        <el-option
                          v-for="item in prePointIdOptions"
                          :key="item.pointId"
                          :label="item.pointName"
                          :value="item.pointId"
                        >
                        </el-option>
                      </el-select>
                    </template>
                  </el-table-column>
                </el-table>
              </div>
            </el-form>
            <!--人员选择-->
            <b class="title">人员信息</b>
            <el-form ref="form" :model="form" label-width="70px">
              <el-form-item label="开始时间" prop="ticketStartTime">
                <el-date-picker
                  :disabled="this.getSopLook"
                  v-model="form.ticketStartTime"
                  type="datetime"
                  placeholder="选择日期时间"
                  align="right"
                  :picker-options="pickerOptions"
                  style="width: 100%"
                  @change="ticketStartTimeChange"
                >
                </el-date-picker>
              </el-form-item>
              <el-form-item label="结束时间" prop="ticketEndTime">
                <el-date-picker
                  :disabled="this.getSopLook"
                  v-model="form.ticketEndTime"
                  type="datetime"
                  placeholder="选择日期时间"
                  align="right"
                  :picker-options="pickerOptions"
                  style="width: 100%"
                  @change="ticketEndTimeChange"
                >
                </el-date-picker>
              </el-form-item>
              <el-form-item label="上锁人" prop="locker">
                <el-select
                  :disabled="this.getSopLook"
                  v-model="form.locker"
                  placeholder="上锁人"
                  clearable
                  style="width: 100%"
                  @change="handlelockerChage"
                >
                  <el-option
                    v-for="dict in this.listLockerOption"
                    :key="dict.value"
                    :label="dict.label"
                    :value="dict.value"
                  />
                </el-select>
              </el-form-item>

              <el-form-item label="共锁人" prop="coLocker">
                <el-button
                  type="primary"
                  @click="addInside"
                  class="gsr"
                  size="mini"
                  disabled
                  >添加内部人员
                </el-button>
                <el-button
                  type="primary"
                  @click="addOutside"
                  size="mini"
                  disabled
                  >添加外部人员
                </el-button>
              </el-form-item>
              <div class="text item">
                <el-table
                  :data="sortedTicketUserDTOList"
                  stripe
                  height="300"
                  style="width: 100%; overflow: -moz-scrollbars-none"
                  class="tabData"
                >
                  <el-table-column prop="userId" label="序号" width="50">
                  </el-table-column>
                  <el-table-column prop="userName" label="共锁人" width="110">
                    <template slot-scope="scope">
                      <span style="color: #2a87ff">{{
                        scope.row.userName
                      }}</span>
                    </template>
                  </el-table-column>
                  <el-table-column
                    prop="userType"
                    label="共锁人来源"
                    width="100"
                  >
                    <template slot-scope="scope">
                      <span>{{
                        scope.row.userType == "0" ? "内部" : "外部"
                      }}</span>
                    </template>
                  </el-table-column>
                  <el-table-column label="" width="80">
                    <template slot-scope="scope">
                      <el-button
                        @click.native.prevent="
                          deleteRow(scope.$index, sortedTicketUserDTOList)
                        "
                        type="text"
                        size="small"
                        disabled
                      >
                        移除
                      </el-button>
                    </template>
                  </el-table-column>
                </el-table>
              </div>
            </el-form>
          </div>
        </el-card>
      </div>
    </div>
    <!-- 添加或修改设备维修单对话框 -->
    <el-dialog
      :visible.sync="open"
      width="450px"
      append-to-body
      style="margin-top: 13%"
    >
      <div slot="title" class="dialog-title">
        <i></i>
        <span class="title">{{ title }}</span>
      </div>
      <el-form ref="dialogForm" :model="dialogForm" label-width="70px">
        <el-form-item label="选择人员" prop="nickName" v-if="insideMumber">
          <el-select
            v-model="dialogForm.nickName"
            placeholder="请选择人员"
            clearable
            style="width: 100%"
            multiple
            @change="changeInsideUser"
          >
            <el-option
              v-for="dict in this.listCoLockerOption"
              :key="dict.value"
              :label="dict.label"
              :value="dict.value"
            />
          </el-select>
        </el-form-item>

        <el-form-item label="人员ID" prop="username" v-if="outsideMumber">
          <el-row>
            <el-col :span="16">
              <el-input
                v-model="dialogForm.username"
                placeholder="请输入人员ID"
                clearable
                style="width: 80%"
                @change="outSideUserInput"
              />
            </el-col>
            <el-col :span="4">
              <el-button type="primary" @click="insertOutSideTable"
                >添加</el-button
              >
            </el-col>
          </el-row>
        </el-form-item>
        <el-row>
          <el-table
            :data="OutSideUserTableData"
            stripe
            height="200"
            v-if="outsideMumber"
          >
            <el-table-column prop="userId" label="序号"> </el-table-column>
            <el-table-column prop="userName" label="人员ID">
              <template slot-scope="scope">
                <span style="color: #2a87ff">{{ scope.row.userName }}</span>
              </template>
            </el-table-column>
            <el-table-column label="操作" width="80">
              <template slot-scope="scope">
                <el-button
                  @click.native.prevent="
                    deleteRow(scope.$index, OutSideUserTableData)
                  "
                  type="text"
                  size="small"
                >
                  移除
                </el-button>
              </template>
            </el-table-column>
          </el-table>
        </el-row>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <!--  内部人员确认-->
        <el-button type="primary" @click="cancel" v-if="insideMumber"
          >确认</el-button
        >
        <!--        外部人员确认-->
        <el-button
          type="primary"
          @click="outSideDialogConfirm"
          v-if="outsideMumber"
          >确认</el-button
        >
        <el-button @click="cancel">取 消</el-button>
      </div>
    </el-dialog>
    <!--    newOperations盒子结束-->
    <!-- 加载 -->
    <div class="loadbox" v-if="isVisible">
      <h5>加载中</h5>
      <i class="el-icon-loading"></i>
    </div>
  </div>
</template>


<script>
import SeparationPoint from "@/components/separationPoint/index.vue";
import WorkShop from "@/components/separationPoint/workshop.vue";
import {
  listJobTicket,
  getJobTicketInfo,
  addJobTicket,
  updateJobTicket,
  deleteIsJobTicket,
  getworkareaList,
} from "@/api/mes/job/job";
import { selectIsSopById, SopUser } from "@/api/mes/sop/sopindex-booz";
import { mapGetters, mapActions } from "vuex";
import { getIsSopPage } from "@/api/mes/sop/sopindex-booz";
import { genCode } from "@/api/system/autocode/rule";
import { listWorkarea } from "@/api/mes/wa/workarea";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
import Treeselect from "@riophae/vue-treeselect";

export default {
  name: "addView",
  dicts: ["ticket_type", "power_type", "point_type", "is_user_type"],
  props: {
    sopProps: {
      type: Array,
      default: () => [],
    },
    jobProps: {
      type: Array,
      default: () => [],
    },
  },
  components: {
    SeparationPoint,
    WorkShop,
    Treeselect,
  },
  data() {
    return {
      //自动生成编码
      autoGenFlag: false,
      openStaffing: true,
      activeName: "second",
      form: {
        sopId: "",
        pointIds: "",
        ticketId: "",
        ticketType: "",
        ticketName: "",
        ticketCode: "",
        ticketContent: "",
        workshopName: "", //车间名称
        workline: "", //区域
        spoint: [], //已选隔离点
        locker: "", //上锁人
        coLocker: "", //共锁人
        ticketStartTime: "", //开始时间
        ticketEndTime: "", //结束时间
        workareaId: null, //作业区域id
        ticketUserDTOList: [
          // {
          //   userId: '',
          //   userName: '',
          //   userRole: '',//作业票角色 暂时不传递 内部人还是外部人
          //   userType: ''//用户类型 上锁人或共锁人
          // }
        ], //所选择的用户
      },
      // 用来清空form
      initialFormState: {
        // 初始状态对象
        sopId: "",
        pointIds: "",
        ticketId: "",
        ticketType: "",
        ticketName: "",
        ticketCode: "",
        ticketContent: "",
        workshopName: "", //车间名称
        workline: "", //区域
        spoint: [], //已选隔离点
        locker: "", //上锁人
        coLocker: "", //共锁人
        ticketStartTime: "", //开始时间
        ticketEndTime: "", //结束时间
        pointDetailVOList: [], //隔离点数据
        ticketUserDTOList: [
          // {
          //   userId: '',
          //   userName: '',
          //   userRole: '',//作业票角色 暂时不传递 内部人还是外部人
          //   userType: ''//用户类型 上锁人或共锁人
          // }
        ], //所选择的用户
      },
      dialogForm: {
        nickName: "",
        username: "",
      },
      // 已选隔离点
      tableData: [],
      orderTableData:[],//排序
      pickerOptions: {
        shortcuts: [
          {
            text: "今天",
            onClick(picker) {
              picker.$emit("pick", new Date());
            },
          },
          {
            text: "昨天",
            onClick(picker) {
              const date = new Date();
              date.setTime(date.getTime() - 3600 * 1000 * 24);
              picker.$emit("pick", date);
            },
          },
          {
            text: "一周前",
            onClick(picker) {
              const date = new Date();
              date.setTime(date.getTime() - 3600 * 1000 * 24 * 7);
              picker.$emit("pick", date);
            },
          },
        ],
      },
      // 是否显示弹出层
      open: false,
      // 弹出层标题
      title: "",
      // 弹框中显示的form表单内容
      insideMumber: false,
      outsideMumber: false,
      points: null, //逆向传递拿到隔离点的数据
      emitWorkShop: null, //车间逆向传递拿到车间相关数据
      emitworklineId: null, //生产线逆向传递拿到数据
      sopOptions: [], //sop下拉
      jobProps: [], //正向传递给车间components
      // 表单校验
      rules: {
        teamCode: [
          { required: true, message: "班组编号不能为空", trigger: "blur" },
        ],
        teamName: [
          { required: true, message: "班组名称不能为空", trigger: "blur" },
        ],
        calendarType: [
          { required: true, message: "清选择班组类型", trigger: "blur" },
        ],
      },
      newticketUserDTOList: [], //为了上锁人单独传递数据
      prePointIdOptions: [], //前置节点的下拉选项
      initprePointIdOptions: [], //前置节点初始化数据选项
      prePointId: null, //回显选中的前置节点id
      relations: [], //维护父子关系的前置节点
      listLockerOption: null, //上锁人下拉数据
      listCoLockerOption: null, //共锁人下拉数据
      OutSideUserTableData: [], //添加外部人员多个表格
      nextUserId: 0, //新增外部人员表格序号自定义
      worklineMap: null, //作业区域拿到的mapjson
      // 部门树选项
      deptOptions: undefined,
      defaultProps: {
        children: "children",
        label: "label",
      },
      showWorkEare: true, //作业区域是否展示
      isVisible: true, // 控制盒子显示状态
    };
  },
  watch: {
    tableData: {
      handler(newVal) {
        // 将 pointId 提取出来并连接成一个字符串
        if (newVal && newVal.length > 0) {
          this.form.pointIds = this.tableData
            .map((item) => item.pointId)
            .join(",");
          // console.log(this.form.pointIds, this.tableData, 'pointIds')
        }
      },
      deep: true,
    },
    "form.ticketStartTime": {
      handler(newVal) {
        if (newVal && newVal.length > 0) {
          console.log(newVal, "编辑监听开始时间");
          this.ticketStartTimeChange(newVal);
        }
      },
    },
  },
  computed: {
    ...mapGetters("sopSelectPoints", [
      "getPointTableData",
      "getSelectSopPoints",
      "getSopEdit",
      "getTicketTitle",
      "getSopLook",
      "getVisibleSopSelect",
    ]),
    // 排序 ticketUserDTOList，将 userRole 为 0 的选项放在前面
    sortedTicketUserDTOList() {
      return this.form.ticketUserDTOList.sort(
        (a, b) => Number(a.userRole) - Number(b.userRole)
      );
    },
  },
  mounted() {
    // // 5秒后隐藏盒子
    setTimeout(() => {
      this.isVisible = false;
    }, 1000);

    this.getTreeselect(); //获取作业区域下拉de
    this.getSopList();
    this.handleOpenStaffing();
    if (this.$route.query.ticketId !== "null") {
      this.getTicket();
      this.form.ticketId = this.$route.query.ticketId;
      if (this.getSopLook) {
        this.setTicketTitle("查看作业票");
      } else {
        this.setTicketTitle("编辑作业票");
      }
    } else {
      this.setSelectSopPoints([]);
      this.setPointTableData([]);
      this.setTicketTitle("新建作业票");
    }
    // console.log(this.getPointTableData, 'this.getPointTableData')
    if (this.getPointTableData) {
      this.tableData = this.getPointTableData.pointDetailVOList.map((item) => {
        return {
          pointId: item.pointId,
          pointName: item.pointName,
          pointType: item.pointType,
          powerType: item.powerType,
        };
      });
    }
  },

  methods: {
    // 编辑的时候给隔离点重新存储值
    ...mapActions("sopSelectPoints", [
      "setSelectSopPoints",
      "setPointTableData",
      "setSopEdit",
      "setTicketTitle",
    ]),
    // 作业区域打开关闭
    openWorkEare() {
      this.showWorkEare = false;
    },
    closeWorkEare() {
      this.showWorkEare = true;
    },
    formatDateTime(date) {
      const year = date.getFullYear().toString().padStart(2, "0");
      const month = (date.getMonth() + 1).toString().padStart(2, "0");
      const day = date.getDate().toString().padStart(2, "0");
      const hours = date.getHours().toString().padStart(2, "0");
      const minutes = date.getMinutes().toString().padStart(2, "0");
      const seconds = date.getSeconds().toString().padStart(2, "0");

      return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
    },
    getTicket() {
      const ticketId = this.$route.query.ticketId;
      getJobTicketInfo(ticketId).then((response) => {
        console.log(response, "编辑拿到路由参数");
        this.orderTableData=response.data.pointDetailVOList.map((point)=>{
          return{
            pointName: point.pointName, // 显示的名称
            pointId: point.pointId, // 对应的值
            pointType: point.pointType,
            powerType: point.powerType,
            prePointId: point.prePointId
          }
        })
        this.workareaName = response.data.workareaName;

        this.form = {
          ...this.form,
          workareaId: response.data.workareaId,
          sopId: response.data.sopId,
          ticketCode: response.data.ticketCode,
          ticketContent: response.data.ticketContent,
          spoint: response.data.pointDetailVOList,
          ticketUserDTOList: response.data.jobTicketUserList
            .filter((item) => item.userRole !== "jtlocker")
            .map((item) => ({
              userName: item.userName,
              userType: item.userType,
              userRole: item.userRole,
              userId: item.userId,
            })),

          locker: response.data.jobTicketUserList
            .filter((item) => item.userRole == "jtlocker")
            .map((item) => item.userName)[0],
          coLocker: response.data.jobTicketUserList.map((item) => {
            return item.userRole !== "jtlocker" ? item.userName : null;
          }),
          ticketStartTime: response.data.ticketStartTime,
          ticketEndTime: response.data.ticketEndTime,
          ticketId: response.data.ticketId,
          ticketName: response.data.ticketName,
          ticketStatus: response.data.ticketStatus,
          ticketType: response.data.ticketType,
          EditBool: true,
        };
        (this.newticketUserDTOList = response.data.jobTicketUserList
          .filter((item) => item.userRole == "jtlocker")
          .map((item) => ({
            userName: item.userName,
            userType: item.userType,
            userRole: item.userRole,
            userId: item.userId,
          }))),
          (this.jobProps = [this.form]);
        // this.listUserOption = response.data.jobTicketUserList
        console.log(this.form, "form");
      });
    },

    getSopList() {
      const query = {
        current: 1,
        size: 100000,
      };
      getIsSopPage(query).then((res) => {
        console.log(res, "sop列表接口");
        // 插入一个默认的空选项
        const defaultOption = {
          sopId: null,
          sopName: "不使用sop模板  ",
        };

        // 将默认选项添加到结果的最前面
        this.sopOptions = [defaultOption, ...res.data.records];
      });
    },
    // sop下拉change事件 可以传递sopOptions一整个对象过去
    handleSelectSOP(value) {
      if (value == null) {
        this.jobProps = [];
        console.log(this.form.sopId, this.form, "sop下拉change事件");
      } else {
        this.jobProps = this.sopOptions.filter((item) => item.sopId == value);

        this.form.ticketType = this.jobProps[0].sopType;

        this.form.ticketName = "sop_";
        selectIsSopById(value).then((response) => {
          console.log(response, "sop-父组件");
          const value = response.data.ticketUserDTOList //找到上锁人  这里一定要先筛选locker再去给表格筛选 否则表格筛选之后直接不会有上锁人数据了
            .filter((item) => item.userRole == "jtlocker")
            .map((item) => item.userName);
          (this.form.locker = value[0]), //map返回的是数字 所以这样写
            // console.log(value,response.data.ticketUserDTOList,'form.locker')
            (this.form.ticketUserDTOList =
              response.data.ticketUserDTOList.filter((item) => {
                return item.userRole == "jtlocker";
              })); //过滤上锁人
          this.tableData = response.data.pointDetailVOList;
          this.form.workareaId = response.data.workareaId;
        });

        console.log(this.jobProps, "父组件jobProps");
      }
    },
    // 清除sop下拉框
    handleClearSop() {
      this.form.ticketType = "";
      this.form.ticketName = "";
    },
    /** 查询作业区域下拉树结构 */
    getTreeselect() {
      const data = {
        current: 1,
        size: -1,
      };
      listWorkarea(data).then((response) => {
        // console.log(response.data.records, '作业区域下拉树形结构');
        // 转换为树形结构
        this.deptOptions = this.transformToTree(response.data.records);
        // console.log(this.deptOptions, 'deptOptions')
        // 使用递归函数查找匹配的节点
        console.log(this.workareaName, "name");
        const selectedTreeNode = this.findNodeById(
          this.deptOptions,
          this.workareaName
        );
        // 调用 handleNodeClick 方法
        if (selectedTreeNode) {
          this.handleNodeClick(selectedTreeNode);
        } else {
          console.log("未找到匹配的节点");
        }
      });
    },
    // 深层次遍历
    findNodeById(nodes, targetId) {
      for (let i = 0; i < nodes.length; i++) {
        const node = nodes[i];
        if (node.id === targetId) {
          return node;
        }
        if (node.children && node.children.length > 0) {
          const foundNode = this.findNodeById(node.children, targetId);
          if (foundNode) {
            return foundNode;
          }
        }
      }
      return null;
    },
    /** 转换数据为树形结构 */
    transformToTree(records) {
      const recordMap = {}; // 创建一个 Map 以存储所有记录
      const tree = []; // 最终返回的树形结构

      // 初始化所有记录到 Map
      records.forEach((record) => {
        recordMap[record.workareaId] = {
          id: record.workareaId,
          label: record.workareaName,
          map: record.map,
          mapImg: record.mapImg,
          children: [],
        };
      });

      // 遍历记录并构建树
      records.forEach((record) => {
        const parentId = record.parentId;

        if (parentId === "0") {
          // 如果是顶层节点，直接添加到树中
          tree.push(recordMap[record.workareaId]);
        } else if (recordMap[parentId]) {
          // 如果有父节点，则将当前节点加入父节点的 children 中
          recordMap[parentId].children.push(recordMap[record.workareaId]);
        }
      });

      return tree;
    },

    // 树节点筛选逻辑
    filterNode(value, data) {
      if (!value) return true; // 如果没有输入值，显示所有节点
      return data.label.indexOf(value) !== -1; // 判断节点 label 是否包含输入值
    },
    // 监听输入框变化
    handleInputChange() {
      this.$refs.tree.filter(this.workareaName); // 调用树的 filter 方法
    },
    // 作业票确认
    async confirm() {
      try {
        // 格式化时间
        this.form.ticketStartTime = this.formatDateTime(
          new Date(this.form.ticketStartTime)
        );
        this.form.ticketEndTime = this.formatDateTime(
          new Date(this.form.ticketEndTime)
        );
        // console.log(this.form, "拿到的所有参数确认");
        const UserList = [
          ...(this.form.ticketUserDTOList || []),
          ...(this.newticketUserDTOList || []),
        ];
        const pointsList = this.tableData.map((item) => {
          return {
            pointId: item.pointId,
            prePointId: item.prePointId,
          };
        });
        const data = {
          pointIds: this.form.pointIds,
          sopId: this.form.sopId,
          ticketCode: this.form.ticketCode,
          ticketContent: this.form.ticketContent,
          ticketEndTime: this.form.ticketEndTime,
          ticketName: this.form.ticketName,
          ticketStartTime: this.form.ticketStartTime,
          ticketType: this.form.ticketType,
          ticketUserDTOList: UserList,
          workareaId: this.emitworklineId,
          pointsList: pointsList,
        };
        const editdata = {
          pointIds: this.form.spoint.join(","),
          sopId: this.form.sopId,
          ticketCode: this.form.ticketCode,
          ticketContent: this.form.ticketContent,
          ticketId: this.form.ticketId,
          ticketEndTime: this.form.ticketEndTime,
          ticketName: this.form.ticketName,
          ticketStartTime: this.form.ticketStartTime,
          ticketType: this.form.ticketType,
          ticketUserDTOList: UserList,
          workareaId: this.emitworklineId,
          pointsList: pointsList,
        };

        // 检查 route.query.ticketId 是否为 null
        console.log(this.$route.query.ticketId, "this.$route.query.ticketId");
        if (this.$route.query.ticketId !== "null") {
          // 调用编辑接口

          const res = await updateJobTicket(editdata);
          if (res.code === 200) {
            // this.$router.go(-1);
            this.$router.push("/job/jobm");
          } else {
            console.error("编辑工单失败", res);
          }
        } else {
          console.log(data, "新增的参数");
          // 调用新增接口
          const res = await addJobTicket(data);
          if (res.code === 200) {
            // this.$router.go(-1);
            this.$router.push("/job/jobm");
          } else {
            console.error("提交工单失败", res);
          }
        }
      } catch (error) {
        console.error("确认过程中发生错误", error);
      }

      console.log("确认");
    },
    // 选中隔离点 前置节点的change函数
    onDropdownVisibleChange(row) {
      console.log(row, "我执行这里拉");

      // 当前节点 ID
      const currentPointId = row.pointId;

      // 获取当前行的 prePointId
      const currentPrePointId = row.prePointId;

      // 已经被选为前置节点的 ID 集合
      const selectedPrePointIds = new Set(
        this.tableData
          .filter((item) => item.prePointId !== null)
          .map((item) => item.prePointId)
      );

      // console.log(selectedPrePointIds, 'selectedPrePointIds')
      // 构建 form.prePointId 数组对象
      this.form.prePointId = this.tableData.map((item) => ({
        pointId: item.pointId,
        prePointId: item.prePointId || null,
      }));
      // 每次都从原始数据开始过滤
      let filteredOptions = [...this.initprePointIdOptions];

      // 过滤规则：
      // 1. 排除自身
      // 2. 排除已经被选为前置节点的隔离点
      // 3. 排除所有已经选为前置节点的节点及其前置节点
      const allExcludedPoints = new Set([currentPointId]);
      this.getAllExcludedPoints(currentPointId, allExcludedPoints);

      filteredOptions = filteredOptions.filter((option) => {
        return !allExcludedPoints.has(option.pointId);
      });

      this.prePointIdOptions = filteredOptions;

      console.log("过滤后的前置节点选项", this.prePointIdOptions);
    },

    // 递归获取所有需要排除的节点
    getAllExcludedPoints(pointId, excludedPoints) {
      const relatedRows = this.tableData.filter(
        (item) => item.prePointId === pointId
      );
      for (const row of relatedRows) {
        excludedPoints.add(row.pointId);
        this.getAllExcludedPoints(row.pointId, excludedPoints);
      }
    },

    // 前置节点改变时的处理函数
    prePointIdChange(row) {
      console.log(row, "前置节点改变");

      // 更新 tableData 中对应行的 prePointId
      const index = this.tableData.findIndex(
        (item) => item.pointId === row.pointId
      );
      if (index !== -1) {
        this.$set(this.tableData, index, row);
      }

      // 重新调用 onDropdownVisibleChange 确保其他节点的选项更新
      this.onDropdownVisibleChange(row);
    },
    // 定义一个排序函数，根据 orderTableData 中 pointName 的顺序对 tableData 进行排序
    sortTableDataByOrder(tableData, orderTableData) {
      // 构建 orderMap，使用 pointName 作为键，索引作为值
      const orderMap = new Map(orderTableData.map((item, index) => [item.pointName, index]))

      return tableData.sort((a, b) => {
        // 如果 pointName 在 orderMap 中，按 orderMap 的索引排序
        // 如果 pointName 不在 orderMap 中，排在最后，并按 pointName 的自然顺序排列
        const indexA = orderMap.has(a.pointName) ? orderMap.get(a.pointName) : Infinity
        const indexB = orderMap.has(b.pointName) ? orderMap.get(b.pointName) : Infinity

        if (indexA === indexB) {
          // 当两者都不在 orderMap 中时，按 pointName 的自然顺序排列
          return a.pointName.localeCompare(b.pointName)
        }

        return indexA - indexB
      })
    },
    // 子组件逆向传递选中的隔离点
    handleSelectPoint(points) {
      // console.log(points, '父组件接收逆向传递选中的隔离点');

      // 1. 去除重复的点，使用 Set 确保每个 pointId 唯一
      const uniquePoints = Array.from(
        new Set(points.map((point) => point.pointId))
      ).map((id) => points.find((point) => point.pointId === id));

      // console.log(uniquePoints, '去重后的选中节点');
      this.tableData = this.sortTableDataByOrder(uniquePoints, this.orderTableData);//去重并排序
      // this.tableData = uniquePoints; // 子组件传递过来的选中节点（去重后）

      // 使用 Set 来存储传递过来的点值
      const newValues = new Set(uniquePoints.map((point) => point.pointId));

      // 2. 删除取消选中的点
      const removedPoints = this.tableData
        .filter((item) => !newValues.has(item.pointId))
        .map((item) => item.pointId); // 记录被删除的点

      this.tableData = this.tableData.filter((item) =>
        newValues.has(item.pointId)
      );

      // 3. 确保新增点不会重复
      const existingValues = new Set(
        this.tableData.map((item) => item.pointId)
      );

      uniquePoints.forEach((point) => {
        // 如果当前传递的点不在已有的点集中，则添加
        if (!existingValues.has(point.pointId)) {
          this.tableData.push({
            pointName: point.pointName, // 显示的名称
            pointId: point.pointId, // 对应的值
            pointType: point.pointType,
            powerType: point.powerType,
            prePointId: null,
          });

          this.prePointIdOptions.push({
            pointName: point.pointName, // 显示的名称
            pointId: point.pointId, // 对应的值
          });
          this.initprePointIdOptions = [...this.prePointIdOptions];
          console.log(this.prePointIdOptions, "前置节点设置下拉");
          existingValues.add(point.pointId);
        }
      });

      // 4. 处理被删除的点，如果这些点作为父节点绑定，则将对应的 prePointId 设置为 null
      this.tableData.forEach((item) => {
        if (removedPoints.includes(item.prePointId)) {
          item.prePointId = null;
        }
      });

      // 5. 从下拉选项中移除被删除的点
      this.prePointIdOptions = this.prePointIdOptions.filter(
        (option) => !removedPoints.includes(option.pointId)
      );
      this.initprePointIdOptions = [...this.prePointIdOptions];

      // 6. 确保下拉选项中仍然保留所有未被删除的点
      const allPoints = uniquePoints.map((point) => ({
        pointName: point.pointName,
        pointId: point.pointId,
      }));

      this.prePointIdOptions = allPoints.filter(
        (option) => !removedPoints.includes(option.pointId)
      );
      this.initprePointIdOptions = [...this.prePointIdOptions];

      // 更新 form.spoint 为最新选中的隔离点数组
      this.form.spoint = uniquePoints.map((point) => point.pointId);
    },
    // 车间逆向传递拿到的隔离点数据产线
    handleProductLineSelected(selectedOption) {
      // console.log(selectedOption, "父组件接收到的 selectedOption");
      this.points = selectedOption;
      this.form.workline = selectedOption.label;
      // console.log(this.worklineMap.length, '父组件接收到的 worklineMap')
    },
    // 车间子组件逆传递车间相关数据车间
    handleWorkshopSelected(selectedOption) {
      console.log(selectedOption, "handleWorkshopSelected");
      // this.emitWorkShop = selectedOption
      // this.form.workshopName = selectedOption.label;//这里是回显车间的 暂时不需要
      this.form.workline = selectedOption.label; //这里是回显作业区域的
      this.emitworklineId = selectedOption.id;
      this.worklineMap = selectedOption.map;
    },
    //   时间选项
    ticketStartTimeChange(value) {
      this.form.ticketStartTime = value;
      // 更新 pickerOptions 中的 disabledDate 方法
      this.updatePickerOptions();
    },
    ticketEndTimeChange(value) {
      this.form.ticketEndTime = value;
    },
    disabledDate(time) {
      const startTime = new Date(this.form.ticketStartTime);
      return startTime && !isNaN(startTime.getTime())
        ? time.getTime() < startTime.getTime()
        : false;
    },
    updatePickerOptions() {
      this.pickerOptions.disabledDate = this.disabledDate;
    },

    reset() {
      (this.form = {
        sopId: "",
        pointIds: "",
        ticketType: "",
        ticketName: "",
        ticketCode: "",
        ticketContent: "",
        workshopName: "", //车间名称
        workline: "", //区域
        spoint: [], //已选隔离点
        locker: "", //上锁人
        coLocker: "", //共锁人
        ticketStartTime: "", //开始时间
        ticketEndTime: "", //结束时间
        ticketUserDTOList: [
          // {
          //   userId: '',
          //   userName: '',
          //   userRole: '',//作业票角色 暂时不传递
          //   userType: ''//用户类型 上锁人或共锁人
          // }
        ],
      }),
        (this.autoGenFlag = false);
    },

    // 侧边x关闭函数
    goBack() {
      this.$router.push("/job/jobm");
    },
    // 添加内部人员
    addInside() {
      this.open = true;
      this.title = "添加内部人员";
      this.insideMumber = true;
      this.outsideMumber = false;
      // this.form.ticketUserDTOList = [];
      this.dialogForm.nickName = "";
    },
    addOutside() {
      this.open = true;
      this.title = "添加外部人员";
      this.insideMumber = false;
      this.outsideMumber = true;
      this.dialogForm.username = null;
    },
    // 取消按钮
    cancel() {
      this.open = false;
    },
    // 人员列表删除
    deleteRow(index, rows) {
      console.log(index, rows, "删除的行");
      const deletedItem = rows[index]; // 获取要删除的项
      rows.splice(index, 1); // 从显示的列表中删除
      const formIndex = this.form.ticketUserDTOList.findIndex(
        (item) => item.userId === deletedItem.userId
      );
      if (formIndex !== -1) {
        this.form.ticketUserDTOList.splice(formIndex, 1); // 从 form.ticketUserDTOList 中删除
      }
    },
    // 上锁人下拉选择change事件
    handlelockerChage(val) {
      console.log(val, "上锁人chage");
      const user = this.listLockerOption.find((item) => item.value === val);

      if (user && this.form.locker !== "") {
        const existingUser = this.form.ticketUserDTOList.find(
          (u) => u.userName === user.label
        );
        if (!existingUser) {
          this.newticketUserDTOList.push({
            userName: user.label,
            userId: user.value,
            userType: 0,
            userRole: "jtlocker",
          });

          console.log(this.newticketUserDTOList, "用户");
        } else {
          // console.log('用户已存在', user.label)
        }
      }
    },

    // 添加内部人员的用户新增到ticketUserDTOList这个数据里
    changeInsideUser(values) {
      const usersinside = values
        .map((value) =>
          this.listCoLockerOption.find((item) => item.value === value)
        )
        .filter(Boolean);

      usersinside.forEach((user) => {
        const existingUser = this.form.ticketUserDTOList.find(
          (u) => u.userName === user.label
        );
        // console.log(usersinside, 'usersinside----67')
        if (!existingUser) {
          this.form.ticketUserDTOList.push({
            userName: user.label,
            userId: user.value,
            userType: 0,
            userRole: "jtcolocker",
          });
          console.log(this.form.ticketUserDTOList, "用户");
        } else {
          // console.log('用户已存在', user.label)
        }
      });
      this.updateCoLocker();

      // console.log(this.form.ticketUserDTOList, '用户')
    },
    // 添加外部人员 输入名称 userType==1是共锁人 0是上锁人 userId==0
    outSideUserInput(event) {
      this.dialogForm.username = event;
    },
    // 添加外部人员弹窗 添加给表格数据的按钮事件
    insertOutSideTable() {
      const newUserName = this.dialogForm.username.trim();
      if (newUserName === "") {
        this.$message.warning("请输入用户名");
        return;
      }
      // 检查新用户是否已存在于表格中
      const existingUser = this.OutSideUserTableData.find(
        (user) => user.userName === newUserName
      );
      if (existingUser) {
        this.$message.warning("该用户已存在");
        return;
      }
      // 添加新用户
      this.OutSideUserTableData.push({
        userName: newUserName,
        userId: this.nextUserId++,
      });

      // 清空对话框表单
      this.dialogForm.username = "";

      // 打印当前的外部人员表格数据
      console.log(this.OutSideUserTableData, "OutSideUserTableData");
    },
    // 添加外部人员 确认弹窗
    outSideDialogConfirm() {
      this.updateCoLocker();
      this.open = false;
    },
    // 更新界面中共锁人下拉框显示的内容
    updateCoLocker() {
      // 检查并补充 ticketUserDTOList 中缺少的用户
      this.OutSideUserTableData.forEach((item) => {
        const existingUser = this.form.ticketUserDTOList.find(
          (u) => u.userName === item.userName
        );
        if (!existingUser) {
          this.form.ticketUserDTOList.push({
            userName: item.userName,
            userId: 0,
            userType: 1,
            userRole: "jtcolocker",
          });
        }
      });

      console.log(this.form.ticketUserDTOList, "最终的 ticketUserDTOList");
    },
    //自动生成编码
    handleAutoGenChange(autoGenFlag) {
      if (autoGenFlag) {
        genCode("JOB_TICKET_CODE").then((response) => {
          this.form.ticketCode = response;
        });
      } else {
        this.form.ticketCode = null;
      }
    },
    //是否开启人员配置界面
    handleOpenStaffing(openStaffing) {
      // 定义一个函数来封装接口调用逻辑
      const fetchUserData = (roleKey) => {
        const data = {
          pageNum: 1,
          pageSize: 10000,
          roleKey: roleKey,
        };
        return SopUser(data)
          .then((res) => {
            // console.log(res, `上锁人 - ${roleKey}`);
            return res; // 返回结果以便后续处理
          })
          .catch((err) => {
            // console.error(err, `请求失败 - ${roleKey}`);
            throw err; // 抛出错误以便捕获
          });
      };

      // 调用两次接口，分别传递不同的 roleKey
      Promise.all([fetchUserData("jtlocker"), fetchUserData("jtcolocker")])
        .then((results) => {
          // 处理两次调用的结果
          const [jtlockerResult, jtcolockerResult] = results;
          console.log(jtlockerResult, jtcolockerResult, "jtlocker 结果");
          this.listLockerOption = jtlockerResult.rows.map((item) => {
            return {
              label: item.nickName,
              value: item.userId,
            };
          });
          this.listCoLockerOption = jtcolockerResult.rows.map((item) => {
            return {
              label: item.nickName,
              value: item.userId,
            };
          });
        })
        .catch((err) => {
          console.error(err, "其中一个请求失败");
        });
      if (openStaffing) {
        console.log(openStaffing, "开启人员配置");
        this.openStaffing = openStaffing;
      } else {
        console.log(openStaffing, "关闭人员配置");
        this.openStaffing = openStaffing;
        // this.activeName = "first";
      }
    },
  },
};
</script>


<style scoped lang="scss">
.newOperations {
  width: 99%;
  height: 100%;
  //background: pink;
  margin: 10px;
  display: flex;
  position: relative;
  .left {
    width: 75%;
    height: 830px;
    // background: #eee;
    margin-right: 10px;
  }
  .lefttree {
    width: 18%;
    height: 100%;
    position: absolute;
    left: 0;
    top: 2%;
    display: flex;
    // background: pink;
    .lefttree-card {
      height: 98%;
      .title {
        display: block;
        width: 30%;
        height: 30px;
        text-align: center;
        margin: 0 0 5%;
        border-bottom: 2px solid #1684fc;
        color: rgb(22, 132, 252);
      }
    }
    .item {
      width: 30px;
      height: 30px;
      font-size: 20px;
      display: flex;
      justify-content: center;
      align-items: center;
      // .btnwork {
      //   width: 100%;
      //   height: 100%;
      //   display: flex; /* 使用 flex 布局 */
      //   justify-content: center; /* 水平居中 */
      //   align-items: center; /* 垂直居中 */
      //   font-size: 20px;
      //   box-sizing: border-box;
      // }
    }
  }
  .right {
    height: 100%;
    flex: 1;

    .right_top {
      // height: 550px;
      height: 840px;
      // background: pink;
    }

    .workTicket_btn {
      position: relative;
      left: 63%;
      height: 30px;
      line-height: 10px;
    }

    .gsr {
      margin-left: 15%;
    }
    .box-card {
      height: 100%;
      overflow-y: auto;
      .clearfix {
        width: 100%;
        position: absolute;
        top: 0;
        line-height: 25px;
        padding: 12px 0 0;
        box-sizing: border-box;
        background: #fff;
        z-index: 10;
      }
    }
    .box-card::-webkit-scrollbar {
      display: none;
    }
    .title {
      display: block;
      width: 25%;
      height: 30px;
      text-align: center;
      margin: 0 0 5%;
      border-bottom: 2px solid #1684fc;
      color: rgb(22, 132, 252);
    }
  }
}
.newOperations::-webkit-scrollbar {
  display: none;
}

//右侧卡片样式开始
.text {
  font-size: 14px;
}

.item {
  margin-bottom: 18px;

  p {
    font-size: 18px;
    font-weight: bolder;
    font-family: SourceHanSansSC-bold;
  }
}

.clearfix:before,
.clearfix:after {
  display: table;
  content: "";
  width: 320px;
}

.clearfix:after {
  clear: both;
}

.box-card {
  // width: 390px;
  width: 95%;
  height: 850px;
}

//右侧卡片样式结束
//隔离点多选框样式
.selects {
  .el-input.el-input--medium.el-input--suffix {
    // 调整箭头符号块的宽度
    width: 175px !important;
  }

  .el-input.el-input--medium.el-input--suffix {
    .el-input__inner {
      // 调整输入框的宽高
      height: 36px !important;
      width: 220px !important;
    }

    .el-input__suffix-inner {
      // 调整箭头符号的位置
      position: absolute;
      right: -45px;
    }
  }

  .el-select__tags {
    // 调整输入框里面的多选不换行
    flex-wrap: nowrap !important;
  }
}
.loadbox {
  width: 100%;
  height: 100%;
  background: rgba($color: #fff, $alpha: 0.9);
  position: absolute;
  left: 0;
  top: 0;
  z-index: 200;
  padding: 18% 45%;
  box-sizing: border-box;
  h5 {
    font-size: 30px;
  }
  .el-icon-loading {
    font-size: 50px;
    margin-left: 12%;
  }
}
//隔离点多选框样式结束
</style>

<style scoped lang="scss" src="@/assets/styles/dialog-title.scss">
</style>
