<script>
import VueDragResizeRotate from "@minogin/vue-drag-resize-rotate";
const { ipcRenderer } = require("electron");
import ImgSetting from "./imgSetting.vue";
import bus from "@/bus";
import PrintDialog from "@/views/design/head/printDialog.vue";
import { mmToPx, newMmToPxFn, extractValue } from "@/utils";
const { checkImageOutsideGrid } = require("../../../server/utils/setImage");
const { pathMap } = require("@/config/index.js");

const path = require("path");

const uuid = require("uuid");

import { mapState } from "vuex";

const img = require("../../../assets/bg_tshirt_shadow.png");
const {
  getDesktopDevice,
  setLocation,
  getLocation,
  getOrderInfoMap,
  setOrderInfo,
  clearMaxLimitRecord,
} = require("@/server/utils/store");

export default {
  components: {
    PrintDialog,
    VueDragResizeRotate,
    ImgSetting,
  },
  props: { factoryType: { type: String, default: "CN" } },
  destroyed() {
    document.removeEventListener("keyup", this.keyup);
    document.removeEventListener("dragover", this.dragover);
    document.removeEventListener("drop", this.drop);
  },
  created() {
    this.$store.commit("getNewGrid");
    ipcRenderer.on("window-size", (event, size) => {
      const { width, height } = size;
      console.log(`接收到窗口尺寸：${width}x${height}`);
      let proportion;

      proportion = 1.4;
      // } else {
      //   proportion = 1.5;
      // }

      this.$store.commit("setWHproportion", proportion);
      this.$store.commit("setWindows", { width, height });
      this.$store.commit("setDefaultproportion", proportion);
      this.$store.commit("setGrid");
    });

    if (!this.countryList.length) {
      this.getAllCountryFn();
    }
  },
  computed: {
    gridWH() {
      // console.log("systemSetting", this.systemSetting);
      // console.log("gridValue", this.systemSetting.gridValue);

      if (
        !this.systemSetting ||
        !this.grid ||
        !this.grid[this.systemSetting.gridValue]
      )
        return { w: 0, h: 0, v: 1 };
      console.log("current", this.grid[this.systemSetting.gridValue]);

      return {
        w: this.grid[this.systemSetting.gridValue].w,
        v: this.grid[this.systemSetting.gridValue].value,
        h: this.grid[this.systemSetting.gridValue].h,
        row: this.grid[this.systemSetting.gridValue].row,
        col: this.grid[this.systemSetting.gridValue].col,
      };
    },
    gridSpacing() {
      const { unit, gridSpacing } = this.systemSetting;
      if (!this.systemSetting || !Object.keys(this.systemSetting).length)
        return { w: 0, h: 0 };
      if (unit === "mm") {
        return {
          w: gridSpacing + "px",
          h: gridSpacing + "px",
        };
      } else if (unit === "inch") {
        let w = this.grid[this.systemSetting.gridValue].w;
        let row = this.grid[this.systemSetting.gridValue].row;
        let col = this.grid[this.systemSetting.gridValue].col;
        let h = this.grid[this.systemSetting.gridValue].h;
        return {
          // w: gridSpacing * ((w - row + 1) / row) + "px",
          w: gridSpacing * (w / row) + "px",
          h: gridSpacing * (h / col) + "px",
        };
      }
      return { w: "480px", h: "540px" };
    },
    viewGridSpacing() {
      const { unit, gridSpacing } = this.systemSetting;
      if (!this.systemSetting || !Object.keys(this.systemSetting).length)
        return { w: 0, h: 0 };
      if (unit === "mm") {
        return {
          w: gridSpacing + "px",
          h: gridSpacing + "px",
        };
      } else if (unit === "inch") {
        let w = 480;
        let row = 16;
        let col = 18;
        let h = 540;
        return {
          w: gridSpacing * (w / row) + "px",
          h: gridSpacing * (h / col) + "px",
        };
      }
      return { w: "480px", h: "540px" };
    },
    computedGridSize() {
      // const getter = this.systemSetting;
      // const num = getter.gridSpacing.slice(0, 2);
      return 10 + "px";
    },

    returnItem() {
      // console.log("returnItem", this.imgList[this.selectIndex]);

      if (this.selectIndex < 0 && this.imgList.length) {
        // this.showImgSetting = false;
        this.selectIndex = 0;
      }
      let item = this.imgList[this.selectIndex];
      // console.log("item", item);

      if (item) {
        // item = JSON.parse(JSON.stringify(item));
        // item.x = Number(item.x) - Number(item.w);
        // item.y = 0;
        return JSON.parse(JSON.stringify(this.imgList[this.selectIndex]));
      }
      this.showImgSetting = false;

      return null;
    },

    ...mapState([
      "desktopDevice",
      "productDetail",
      "WHproportion",
      "grid",
      "windowWH",
      "countryList",
      "desktoVersion",
      "orderType",
    ]),
  },
  data() {
    return {
      predefineColors: [
        "#ff4500",
        "#ff8c00",
        "#ffd700",
        "#90ee90",
        "#00ced1",
        "#1e90ff",
        "#c71585",
        "rgba(255, 69, 0, 0.68)",
        "rgb(255, 120, 0)",
        "hsv(51, 100, 98)",
        "hsva(120, 40, 94, 0.5)",
        "hsl(181, 100%, 37%)",
        "hsla(209, 100%, 56%, 0.73)",
        "#c7158577",
      ],
      actionList: [],
      checkList: [],
      oldImgList: [],

      parentWidth: 0,
      backColor: "#77797a",
      gridBg: "#ffffff",
      systemSetting: {},
      detail: {},
      imgHeight: 0,
      selectImgList: [],
      bus: 0,
      deviceStoreWatcher: "",
      showImgSetting: true,
      printDialogShow: true,
      parentHeight: 0,
      width: 0,
      selectIndex: -1,
      height: 0,
      x: 0,
      y: 0,
      imgList: [],
      viewImgList: [],
      selectImgIndexList: [],
      currentImgIndex: 0,
      isView: false,
      imgHistoryList: [[]],
      imgHistoryIndex: 0,
      row: 16,
      img,
      col: 18,
      oldImgStyle: "",
      drrDom: null,
      imgDom: null,
      leftPosition: "22%",
      topPosition: "52%",
      currentImgData: null,
      newDesktopDevice: getDesktopDevice(),
      downloadLocation1: getLocation("downloadLocation1"),
      downloadLocation2: getLocation("downloadLocation2"),
      logList: [],
      activeName: "1",
      localeData: getOrderInfoMap(),
      faceType: "",
      expandStatus: {},
      detectResult: null, // 检测结果
      imgNaturalSize: { width: 0, height: 0 }, // 图片原始尺寸
      productMark: "",
      isMove: false,
      isOver: false,
      dialogVisible: false,
      isForcedProduction: false,
    };
  },
  watch: {
    imgList: {
      async handler() {
        this.$store.commit("changeImgList", this.imgList);
      },
      deep: true,
      // immediate: true,
    },
    selectIndex(val) {
      console.log(313, val);

      if (this.selectIndex >= 0) {
        if (!this.showImgSetting) {
          this.showImgSetting = true;
        }
      } else {
        this.showImgSetting = false;
      }
    },
    desktopDevice() {
      this.newDesktopDevice = getDesktopDevice();
      this.detail = {};

      this.imgList = [];
      this.selectImgList = [];
      this.selectIndex = -1;
      this.selectImgIndex = 0;
    },
    desktoVersion(newValue) {
      if (newValue) {
        this.imgList = [];
        this.selectImgList = [];
        this.selectIndex = -1;
        this.selectImgIndex = 0;
        this.detail = {};
      }
    },

    productDetail(newValue) {
      this.detail = { ...newValue };
      console.log(325, this.detail);

      if (Object.keys(this.detail).length) {
        if (this.newDesktopDevice == 3) {
          this.logList.unshift(
            `订单：${this.detail.newId}-${
              this.selectImgList.length > 1 ? this.faceType : "S"
            }面 已查询`,
          );
        }
        try {
          if (typeof this.detail.imageAry == "string") {
            this.detail.imageAry = JSON.parse(this.detail.imageAry);
          }
        } catch (error) {
          console.log(error);

          this.detail.imageAry = [{ title: "正", url: this.detail.imageAry }];
        }

        this.detail.imageAry = this.detail.imageAry.sort((a, b) => {
          // 检查 a.title 是否为 '正' 或 'A'
          const isAPriority = a.title === "正" || a.title === "A";
          // 检查 b.title 是否为 '正' 或 'A'
          const isBPriority = b.title === "正" || b.title === "A";

          // 如果 a 是优先项而 b 不是，a 排前面
          if (isAPriority && !isBPriority) return -1;
          // 如果 b 是优先项而 a 不是，b 排前面
          if (!isAPriority && isBPriority) return 1;
          // 其他情况保持原顺序（稳定排序）
          return 0;
        });
      } else {
        this.imgList = [];
        this.selectImgList = [];
        this.selectIndex = -1;
        this.selectImgIndex = 0;
      }

      // console.log(249, this.detail.imageAry);
    },
    col: {
      handler(newValue) {
        const positionMap = {
          8: { left: "36%", top: "36%" },
          12: { left: "32%", top: "43%" },
          16: { left: "26%", top: "49%" },
          18: { left: "22%", top: "52%" },
          21: { left: "22%", top: "56%" },
          22: { left: "19%", top: "60%" },
          24: { left: "12%", top: "56%" },
        };

        // 查找对应的位置设置
        const position = positionMap[newValue];
        if (position) {
          this.leftPosition = position.left;
          this.topPosition = position.top;
        }

        if (this.imgList?.length) {
          this.getBackFile({
            files: this.imgList,
            size: this.detail.designImageSize || null,
          });
        }
      },
      immediate: true,
    },

    isView: {
      handler(newValue) {
        if (!newValue) {
          this.$nextTick(() => {
            this.drrDom = document.getElementsByClassName("drr")[0];
            this.imgDom = document.getElementById("imgBox");
            // console.log(257, this.imgDom);
            if (this.imgDom)
              this.imgDom.style.webkitClipPath = this.oldImgStyle;
          });
        } else {
          this.drrDom = "";
          this.imgDom = "";
        }
      },
      immediate: true,
    },
    systemSetting: {
      handler() {
        if (this.imgList.length > 0) {
          this.$refs.imgSetting?.getCurrentItem(this.imgList[this.selectIndex]);
        }
      },
      deep: true,
    },
    newDesktopDevice: {
      handler(val) {
        // console.log(122, val);

        if (val == 3) {
          this.systemSetting.gridValue = 5;
        } else {
          this.systemSetting.gridValue = 0;
          this.$store.commit("setWHproportion", 1.4);
          this.$store.commit("setGrid");
        }
      },
      immediate: true,
    },
  },
  methods: {
    // 重构为可手动触发的方法

    changePrintDialogShow() {
      this.printDialogShow = !this.printDialogShow;
    },
    async drop(e) {
      let that = this;
      e.stopPropagation();
      //阻止浏览器默认打开文件的操作
      e.preventDefault();
      // console.log(e);
      const files = e.dataTransfer.files;
      if (files.length === 0) return;
      for (let i = 0; i < files.length; i++) {
        if (files[i].type !== "image/png") {
          return that.$message.warning("只能上传png格式文件");
        }
        let formData = new FormData();
        formData.append("file", files[i]);
        let { data } = await that.$api.post("/uploadImage", formData, {
          headers: {
            "Content-Type": "application/x-www-form-urlencoded",
          },
        });
        that.selectImgIndex = 0;
        that.addFile(data, () => {
          that.imgHistoryList.push(JSON.parse(JSON.stringify(that.imgList)));
        });
      }
    },
    dragover(e) {
      e.stopPropagation();
      //阻止浏览器默认打开文件的操作
      e.preventDefault();
      e.dataTransfer.dropEffect = "copy";
    },
    keyup(e) {
      // console.log(e);
      if (e.keyCode == 90 && e.ctrlKey) {
        let i = this.imgHistoryList.length - (2 + this.imgHistoryIndex);
        if (this.imgHistoryList[i]) {
          this.imgList = JSON.parse(JSON.stringify(this.imgHistoryList[i]));
          this.imgHistoryIndex = this.imgHistoryIndex + 1;
        }
      }
      if (this.selectIndex >= 0) {
        if (e.keyCode === 38) {
          //上
          this.$set(
            this.imgList[this.selectIndex],
            "y",
            Number(this.imgList[this.selectIndex].y) - 1,
          );
          this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
        }
        if (e.keyCode === 40) {
          //下
          this.$set(
            this.imgList[this.selectIndex],
            "y",
            Number(this.imgList[this.selectIndex].y) + 1,
          );
          this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
        }
        if (e.keyCode === 37) {
          //左
          this.$set(
            this.imgList[this.selectIndex],
            "x",
            Number(this.imgList[this.selectIndex].x) - 1,
          );
          this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
        }
        if (e.keyCode === 39) {
          //右
          this.$set(
            this.imgList[this.selectIndex],
            "x",
            Number(this.imgList[this.selectIndex].x) + 1,
          );
          this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
        }
      }
      if (e.keyCode === 8) {
        if (this.selectIndex >= 0) {
          this.imgList.splice(this.selectIndex, 1);
          if (this.imgList.length > 0) {
            this.selectIndex = 0;
          } else {
            this.selectIndex = -1;
          }
        }
      }
    },

    indexChange(v) {
      console.log("indexChange");
      if (this.imgList.length === 0) return;
      let index = !this.imgList[this.selectIndex] ? 0 : this.selectIndex;

      let item = this.$store.state.actionList[v];
      if (!item) return;

      if (item.t === "drag") {
        this.$set(this.imgList[index], "x", item.x);
        this.$set(this.imgList[index], "y", item.y);
      } else if (item.t === "resize") {
        this.$set(this.imgList[index], "x", item.x);
        this.$set(this.imgList[index], "y", item.y);
        this.$set(this.imgList[index], "w", item.w);
        this.$set(this.imgList[index], "h", item.h);
      }
    },
    getOneMmsPx() {
      // 创建一个1mm宽的元素插入到页面，然后坐等出结果
      let div = document.createElement("div");
      div.id = "mm";
      div.style.width = "1mm";
      document.querySelector("body").appendChild(div);
      // 原生方法获取浏览器对元素的计算值
      let mm1 = document.getElementById("mm").getBoundingClientRect();

      return mm1.width;
    },
    setDesignImg(title) {
      let img = this.selectImgList.find((it) => it.title === title);
      if (img) {
        // console.log(this.detail.designImageSize, "this.detail.size");
        this.getBackFile(
          { files: [img], size: this.detail.designImageSize },
          () => {
            this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
          },
        );
      }
    },
    selectImg(it, index) {
      if (this.isView) {
        this.isView = false;
      }
      this.$nextTick(() => {
        // this.selectImgIndexList.push(i)
        let item = this.imgList.find((img) => img.fileName === it.fileName);
        if (item) return;
        this.selectImgIndex = index;
        // console.log(this.detail.designImageSize);
        let size = null;
        if (
          this.detail.mssWidth &&
          this.detail.adjustable &&
          this.detail.mssHeight
        ) {
          size = {
            width: this.detail.mssWidth,
            height: this.detail.mssHeight,
          };
        }
        this.getBackFile({ files: [it], size }, () => {
          this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
        });
        this.imgDom = document.getElementById("imgBox");
        if (this.imgDom) this.imgDom.style.webkitClipPath = "none";
      });
      // setTimeout(() => {}, 300);
      // this.selectImgIndexList = Array.from(new Set(this.selectImgIndexList))
      // this.getBackFile({ files: [it], size });
    },
    ev(type) {
      if (this.selectIndex < 0 && this.imgList.length) {
        this.selectIndex = 0;
      }
      // if (this.selectIndex === -1) this.selectIndex = 0
      if (!this.imgList[this.selectIndex]) return;

      let w = document.getElementById("line").clientWidth / 2;
      let h = document.getElementById("line").clientHeight / 2;
      let dom = document.getElementsByClassName("drr")[this.selectIndex];
      let z_index;
      if (dom) {
        z_index =
          dom.style.zIndex === "" || !dom.style.zIndex ? 0 : dom.style.zIndex;
      }
      let gw = Number(this.gridWH.w);
      let gh = Number(this.gridWH.h);
      let imgW = this.imgList[this.selectIndex].w;
      let imgH = this.imgList[this.selectIndex].h;
      // 计算容器和图片的宽高比
      const containerRatio = gw / gh;
      const imageRatio = imgW / imgH;

      switch (type) {
        case "cover":
          if (imageRatio >= containerRatio) {
            // 宽度铺满，高度自适应
            let r = gw / imgW;
            this.$set(this.imgList[this.selectIndex], "w", gw);
            this.$set(this.imgList[this.selectIndex], "h", imgH * r);
          } else {
            // // 高度铺满，宽度自适应
            let r = gh / imgH;
            // console.log("比例", r);

            this.$set(this.imgList[this.selectIndex], "h", gh);
            this.$set(this.imgList[this.selectIndex], "w", imgW * r);
          }

          this.$set(this.imgList[this.selectIndex], "x", Number(w));
          this.$set(this.imgList[this.selectIndex], "y", Number(h));

          this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
          break;
        case "center":
          this.$set(this.imgList[this.selectIndex], "x", Number(w));
          this.$set(this.imgList[this.selectIndex], "y", Number(h));
          this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
          break;
        case "x_center":
          this.$set(this.imgList[this.selectIndex], "x", Number(w));

          this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
          break;
        case "y_center":
          this.$set(this.imgList[this.selectIndex], "y", Number(h));
          this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
          break;
        case "add_index":
          dom.style.zIndex = Number(z_index) + 1;
          // console.log(dom.style.zIndex);
          this.$set(
            this.imgList[this.selectIndex],
            "zIndex",
            this.imgList[this.selectIndex].zIndex + 1,
          );
          this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
          break;
        case "reduce_index":
          dom.style.zIndex = Number(z_index) - 1;
          // console.log(dom.style.zIndex);
          this.$set(
            this.imgList[this.selectIndex],
            "zIndex",
            this.imgList[this.selectIndex].zIndex - 1,
          );
          this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
          break;
        default:
          break;
      }
    },
    formChange(form) {
      console.log("formChange");
      // if (this.selectIndex === -1) this.selectIndex = 0
      if (!this.imgList[this.selectIndex]) return;
      let f = JSON.parse(JSON.stringify(form));
      let x_mm = f.x;
      let w_mm = f.w;
      let h_mm = f.h;
      let y_mm = f.y;
      this.$set(this.imgList[this.selectIndex], "x", x_mm);
      this.$set(this.imgList[this.selectIndex], "y", y_mm);
      this.$set(this.imgList[this.selectIndex], "w", w_mm);
      this.$set(this.imgList[this.selectIndex], "h", h_mm);
      this.$set(this.imgList[this.selectIndex], "r", f.r);
      this.$set(this.imgList[this.selectIndex], "zIndex", f.zIndex);
      this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
    },
    close() {
      this.showImgSetting = false;
    },
    dragStop(data, item) {
      this.$set(item, "y", data.y);
      this.$set(item, "x", data.x);
      this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
      this.getCutArea();
    },
    resizeStop(data, item) {
      if (this.selectIndex < 0 && this.imgList.length) this.selectIndex = 0;
      this.$set(item, "y", data.y);
      this.$set(item, "w", data.w);
      this.$set(item, "h", data.h);
      this.$set(item, "x", data.x);
      this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
      if (!this.drrDom && !this.imgDom) {
        this.drrDom = document.getElementsByClassName("drr")[0];
        this.imgDom = document.getElementById("imgBox");
      }
      this.getCutArea();
    },
    resizing() {},
    rotating(data, item) {
      this.$set(item, "r", data.angle);
      this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
    },
    outsideClick(e) {
      if (
        !(
          e.target.className.includes("drr") ||
          e.target.className.includes("sucaitu-img")
        )
      ) {
        this.selectIndex = -1;
        this.close();
      }
    },
    selectItem(index) {
      let dom = document.getElementsByClassName("drr");
      // console.log("dom", dom);

      for (let i = 0; i < dom.length; i++) {
        if (index !== i) {
          dom[i].classList.remove("active");
          dom[i].classList.add("inactive");
        }
      }

      this.selectIndex = index;
    },
    deSelect() {
      this.close();
      this.selectIndex = -1;
    },
    delImg(index) {
      // console.log(index, "index");
      this.imgList.splice(index, 1);
      if (this.imgList.length > 0) {
        this.selectIndex = 0;
        this.showImgSetting = true;
      } else {
        this.selectIndex = -1;
      }
      this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
    },
    fileToBase64(file) {
      return new Promise((resolve, reject) => {
        // 创建一个新的 FileReader 对象
        const reader = new FileReader();
        // 读取 File 对象
        reader.readAsDataURL(file);
        // 加载完成后
        reader.onload = function() {
          // 将读取的数据转换为 base64 编码的字符串
          const base64String = reader.result;
          // 解析为 Promise 对象，并返回 base64 编码的字符串
          resolve(base64String);
        };

        // 加载失败时
        reader.onerror = function() {
          reject(new Error("Failed to load file"));
        };
      });
    },
    getComputedName(title) {
      let img = this.selectImgList.find(
        (it) => it.title === title || it.title.includes(title),
      );
      return img?.designId;
    },
    getComputedTitle(title) {
      // console.log(this.selectImgList, "this.selectImgList");
      let img = this.selectImgList.find(
        (it) => it.title === title || it.title.includes(title),
      );
      return img?.productionFile;
    },
    getBackFile({ files, size }, callback) {
      const isCp = this.productMark == "custom_part" ? true : false;
      let that = this;
      let bw = document.getElementById("line");
      let bh = bw.clientHeight;
      bw = bw.clientWidth;
      this.isView = false;
      this.isMove = false;

      for (let i = 0; i < files.length; i++) {
        files[i].url = files[i]?.productionFile || files[i].url;
        that.$nextTick(async () => {
          let w = bw / 2;
          let h = bh / 2;
          let width_px, height_px, rate, x, y;
          let data = await that.getImageSize(files[i].url);
          const isCut = files[i].isCut;
          if (size && !isCut) {
            if (isCp) {
              width_px = newMmToPxFn(size.width);
              height_px = newMmToPxFn(size.height);
            } else {
              width_px = mmToPx(size.width);
              height_px = mmToPx(size.height);
            }

            x = w;
            y = height_px / 2;
            rate = height_px / width_px;
            // }

            if (this.newDesktopDevice == 3) {
              const scale = bh / data.height;
              width_px = data.width * scale;
              height_px = data.height * scale;
              x = (bw - data.w) / 2;
              y = h;
              rate = height_px / width_px;
            }
          } else {
            rate = data.height / data.width;

            if (rate > 1) {
              height_px = bh * (7.5 / 10);
              width_px = height_px / rate;
              x = w;
              y = height_px / 2;
            } else {
              width_px = bw * (2 / 3);
              height_px = width_px * rate;
              x = width_px / 2;
              y = height_px / 2;
            }
          }
          this.currentImgData = { ...data };
          that.imgList = [];
          that.imgList.push({
            url: files[i].url,
            fileName: files[i].fileName,
            rate,
            w: width_px,
            zIndex: that.imgList.length,
            x,
            y,
            h: height_px,
            r: 0,
          });
          that.selectIndex = that.imgList.length - 1;
          that.showImgSetting = true;

          isCp ? that.ev("x_center") : that.ev("cover");
          if (isCut) that.ev("cover");
          this.$nextTick(async () => {
            const {
              isImageBiggerThanGrid,
              hasOutsideValidPixel,
            } = await checkImageOutsideGrid();

            if (isImageBiggerThanGrid && hasOutsideValidPixel) {
              this.isOver = hasOutsideValidPixel;
            } else if (!isImageBiggerThanGrid) {
              this.isOver = isImageBiggerThanGrid;
            } else if (isImageBiggerThanGrid && !hasOutsideValidPixel) {
              this.isOver = hasOutsideValidPixel;
            }
          });

          if (i === files.length - 1) {
            callback && callback();
          }
        });
      }
    },
    addFile(file, callback) {
      let that = this;
      let bw = document.getElementById("line").clientWidth;
      console.log("addFile");

      // let bh = document.getElementById("line").clientHeight;
      that.$nextTick(() => {
        that.getImageSize(file.url).then((data) => {
          let w = document.getElementById("line").clientWidth / 2;
          let rate = data.height / data.width;
          that.imgList = [];
          that.imgList.push({
            url: file.url,
            w: bw * (2 / 3),
            rate,
            fileName: file.fileName,
            zIndex: that.imgList.length,
            x: w,
            y: (bw * (2 / 3) * rate) / 2,
            h: bw * (2 / 3) * rate,
            r: 0,
          });
          // console.log(570, that.imgList);
          that.selectIndex = that.imgList.length - 1;
          that.showImgSetting = true;
          callback && callback(file);
        });
      });
    },
    listenUpload() {
      // let that = this;
      // document.getElementById("img").onmousedown = function(e) {
      //   e.preventDefault();
      // };
      // that.parentWidth = document.getElementById("img").clientWidth;
      // that.parentHeight = document.getElementById("img").clientHeight;
      // let dp = document.getElementsByClassName("container")[0];
      // dp.addEventListener("dragover", this.dragover);
      // dp.addEventListener("drop", this.drop);
    },
    getImageSize(url) {
      return new Promise(function(resolve, reject) {
        let image = new Image();
        image.onload = function() {
          resolve({
            width: image.width,
            height: image.height,
          });
        };
        image.onerror = function() {
          reject(new Error("error"));
        };
        image.src = url;
      });
    },

    /**
     * 根据主题颜色修改图片颜色
     * @param  {[type]}   imgUrl    图片url
     * @param  {[type]}  color 主题颜色
     * @param  {Function} callback  返回值 返回base64
     */
    changeImageColor(color = "#00ff7f", callback) {
      let threshold = 114; //默认颜色阀值 为 114 －>和默认图相关
      let img = new Image();
      img.src = require("../../../assets/bg_tshirt_shadow.png");
      let newR = parseInt("0x" + color.substr(1, 2));
      let newG = parseInt("0x" + color.substr(3, 2));
      let newB = parseInt("0x" + color.substr(5, 2));
      //图片加载后进行处理
      img.onload = function() {
        let width = img.width,
          height = img.height,
          canvas = document.createElement("canvas"),
          ctx = canvas.getContext("2d");
        canvas.width = width;
        canvas.height = height;
        // 将源图片复制到画布上
        ctx.drawImage(img, 0, 0, width, height);
        // 获取画布的像素信息
        let imageData = ctx.getImageData(0, 0, width, height),
          data = imageData.data;
        // 对像素集合中的单个像素进行循环，每个像素是由4个通道组成，所以要注意
        let i = 0;
        while (i < data.length) {
          let r = data[i++],
            g = data[i++],
            b = data[i++],
            a = data[i++];
          //计算透明度
          let alp = (255 - r) / (255 - threshold);
          //判断是否透明
          let isTransparent = r == 255 && g == 255 && b == 255 && a == 255;
          if (isTransparent) {
            data[i - 1] = 0;
          } else {
            data[i - 4] = newR;
            data[i - 3] = newG;
            data[i - 2] = newB;
            data[i - 1] = a !== 255 ? 255 - a : alp * 255; //处理透明的图片和不透明的图片
          }
        }
        // 将修改后的代码复制回画布中
        ctx.putImageData(imageData, 0, 0);
        // 图片导出为 png 格式
        let imgType = "png";
        let imgData = canvas.toDataURL(imgType);
        callback && callback(imgData);
      };
      return img;
    },

    async cutImgFn() {
      // console.log("detail", this.detail);
      if (this.detail.diyId) {
        await this.downloadImg(1);
      }
      this.checkList = JSON.parse(JSON.stringify(this.selectImgList));
      try {
        const processQueue = await Promise.all(
          this.checkList.map(async (el) => {
            try {
              const outputDir = path.dirname(el.productionFile);

              const outputFileName = `${uuid.v4()}.png`;
              const outputPath = path.join(outputDir, outputFileName);
              const params = {
                inputPath: el.productionFile,
                outputPath: outputPath,
              };
              const res = await this.$api.post("/processImage", params);

              return {
                fileName: outputFileName,
                productionFile: res.msg[0]?.outputPath,
                designId: el.designId,
              };
            } catch (error) {
              console.error(`处理失败: ${el.productionFile}`, error);
            }
          }),
        );
        // console.log("processQueue", processQueue);

        // 等待所有异步操作完成
        await new Promise((resolve) => setTimeout(resolve, 100));
        const newMap = new Map(processQueue.map((el) => [el.designId, el]));
        console.log("newMap", newMap);

        this.selectImgList.forEach((el) => {
          if (newMap.has(el.designId)) {
            el.fileName = newMap.get(el.designId).fileName;
            el.url = newMap.get(el.designId).productionFile;
            el.isCut = true;
            el.productionFile = newMap.get(el.designId).productionFile;
          }
        });

        if (this.imgList.length) {
          const fileNameExists = this.checkList.some(
            (el) => el.fileName === this.imgList[0].fileName,
          );
          if (fileNameExists) {
            this.imgList = [];
            this.selectIndex = -1;
          }
        }
        console.log("this.selectImgList", this.selectImgList);

        this.checkList = [];
        this.getBackFile({ files: [this.selectImgList[0]] });
      } catch (error) {
        console.error("错误", error);
      }
    },
    // startLoading,
    // endLoading,

    handleClick(event) {
      // 获取点击的元素
      let currentElement = event.target;
      if (!this.isView && this.imgDom) {
        this.oldImgStyle = this.imgDom.style.webkitClipPath || "none";
      }
      // 确保点击的元素在包含 container 类名的元素内
      if (currentElement.closest(".container")) {
        // 如果点击的元素不是 boxShaow，执行方法
        if (!currentElement.closest(".boxShaow")) {
          this.isView = !this.isView;
        }
      }

      this.$store.commit("setIsPreView", this.isView);
    },
    async downloadImg(type) {
      let res = await this.$api.post(
        pathMap["downloadBySubOrderNumber"][this.orderType],
        {
          ids: [this.detail.id],
          device: this.newDesktopDevice,
          orderType: this.orderType,
        },
      );
      if (res.data.length === 0) return this.$message.warning("未找到素材图！");
      let imgList = [];
      res.data.forEach((el) => {
        imgList = imgList.concat(el.list || []);
      });
      let arr = [];
      res.data.forEach((el) => {
        if (el.list) {
          el.list.forEach((it) => {
            arr.push(it);
          });
        }
      });
      res.data = arr
        .filter((el) => el.type !== 1)
        .map((el, index) => {
          el.designId = el.designId || index;
          el.title = extractValue(el.designId);
          return el;
        });
      this.selectImgList = [...res.data];
      // console.log(823, this.selectImgList);
      if (type == 1) return;
      this.imgList = [];
      this.selectIndex = -1;
      this.selectImgIndex = 0;
      this.getBackFile({ files: [this.selectImgList[0]] });
    },
    getStyleValue(value, defaultValue = 0) {
      return value
        ? parseFloat(value.replace("px", "")) || defaultValue
        : defaultValue;
    },
    getInset(top = 100, right = 0, bottom = 0, left = 100) {
      return `inset(${100 - top}% ${right}% ${bottom}% ${100 - left}%)`;
    },
    getDrag() {
      this.drrDom = document.getElementsByClassName("drr")[0];
      this.imgDom = document.getElementById("imgBox");

      this.getCutArea();
    },
    getCutArea() {
      this.isMove = true;
      if (!this.drrDom) return;

      let gradient = "none";

      const style = this.drrDom.style;

      if (style.transform) {
        const result = style.transform.split("(")[1].split(")")[0];

        if (result !== "0deg") {
          return;
        }
      }
      const newLeft = this.getStyleValue(style.left);
      const newTop = this.getStyleValue(style.top);
      const newWidth = this.getStyleValue(style.width, 100); // 默认宽度防止除零错误
      const newHeight = this.getStyleValue(style.height, 100);
      const { w, h } = this.gridWH;

      const isOverRight = w < newWidth + newLeft;
      const isOverLeft = newLeft < 0;
      const isOverBottom = h < newTop + newHeight;
      const isOverTop = newTop < 0;

      let top = ((newTop + newHeight) / newHeight) * 100;
      let right = ((newWidth + newLeft - w) / newWidth) * 100;
      let bottom = ((newTop + newHeight - h) / newHeight) * 100;
      let left = ((newLeft + newWidth) / newWidth) * 100;

      if (isOverRight && isOverTop && isOverLeft && isOverBottom) {
        // console.log("四面");
        gradient = this.getInset(top, right, bottom, left);
      } else if (isOverRight && isOverTop && isOverLeft) {
        // console.log("左右上");
        gradient = this.getInset(top, right, 0, left);
      } else if (isOverRight && isOverBottom && isOverLeft) {
        // console.log("左右下");
        gradient = this.getInset(100, right, bottom, left);
      } else if (isOverTop && isOverBottom && isOverLeft) {
        // console.log("左上下");
        gradient = this.getInset(top, 0, bottom, left);
      } else if (isOverTop && isOverBottom && isOverRight) {
        // console.log("右上下");
        gradient = this.getInset(top, right, bottom, 100);
      } else if (isOverRight && isOverTop) {
        // console.log("右上");
        gradient = this.getInset(top, right);
      } else if (isOverRight && isOverBottom) {
        // console.log("右下");
        gradient = this.getInset(100, right, bottom);
      } else if (isOverTop && isOverLeft) {
        // console.log("左上");
        gradient = this.getInset(top, 0, 0, left);
      } else if (isOverLeft && isOverBottom) {
        // console.log("左下");
        gradient = this.getInset(100, 0, bottom, left);
      } else if (isOverLeft && isOverRight) {
        // console.log("左右");
        gradient = this.getInset(100, right, 0, left);
      } else if (isOverTop && isOverBottom) {
        // console.log("上下");
        gradient = this.getInset(top, 0, bottom, 100);
      } else if (isOverRight) {
        // console.log("右");
        gradient = this.getInset(100, right);
      } else if (isOverBottom) {
        // console.log("下");
        gradient = this.getInset(100, 0, bottom);
      } else if (isOverTop) {
        // console.log("上");
        gradient = this.getInset(top);
      } else if (isOverLeft) {
        // console.log("左");
        gradient = this.getInset(100, 0, 0, left);
      } else {
        // console.log("中间");
      }
      this.imgDom.style.webkitClipPath = gradient;
    },
    async getAllCountryFn() {
      try {
        let { data } = await this.$api.post("/getAllCountry");
        this.$store.commit("setCountry", data);
      } catch (error) {
        console.log(error);
      }
    },
    getWHproportion(data) {
      if (this.gridWH.col == 8) {
        return data + 1.8;
      } else if (this.gridWH.col == 12) {
        return data + 0.8;
      } else if (this.gridWH.col == 21) {
        return 1.4;
      } else if (this.gridWH.col == 22) {
        return 1.4;
      } else if (this.gridWH.col == 24) {
        return 1.2;
      } else {
        return data;
      }
    },
    clearImagecCache() {
      this.$confirm(
        "清除图片缓存后，Ctrl+z则将无法回退上一生产单的图片，确实是否进行该操作？",
        "提示",
        {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
        },
      ).then(async () => {
        try {
          this.imgList = [];
          this.selectImgList = [];
          this.selectIndex = -1;
          this.selectImgIndex = 0;
          this.detail = {};
          await this.$api.post("/cleanDirectorySync");
          this.$message.success("清除图片缓存成功");
        } catch (error) {
          console.error("清理目录时发生错误:", error.msg);
          this.$message.error("清理目录时发生错误,请重试");
        }
      });
    },
    changeLocation(v) {
      ipcRenderer.send("request-select-folder");
      const handleFolderResult = (event, folderPath) => {
        ipcRenderer.removeListener("select-folder-result", handleFolderResult);
        if (folderPath) {
          this[v] = folderPath;
          setLocation(folderPath, v);
        }
      };
      ipcRenderer.on("select-folder-result", handleFolderResult);
    },
    tabHandleClick() {},
    formatLog(text) {
      // 这里假设文本格式是固定的
      return text
        .replace(
          `订单：${this.detail.newId}`,
          `<strong>订单：${this.detail.newId}</strong>`,
        )

        .replace(/生产完成/, '<span style="color:#85ce61">生产完成</span>')
        .replace(/未生产完成/, '<span style="color:#f56c79">未生产完成</span>');
    },
    clearLocalFn() {
      setOrderInfo([]);
      clearMaxLimitRecord([]);
      this.localeData = [];
    },
    // 切换单个 Map Key 的展开/收起状态
    toggleExpand(mapKey) {
      // 用 $set 确保响应式（Map Key 可能为非字符串类型）
      this.$set(this.expandStatus, mapKey, !this.expandStatus[mapKey]);
    },
    // 格式化 Map Value，美化排版，保留所有内部 key
    formatJson(data) {
      if (typeof data !== "object" || data === null) {
        return JSON.stringify(data, null, 2);
      }
      // 自动保留 Value 内部的所有 key，美化缩进
      return JSON.stringify(data, null, 2);
    },

    onImageLoad(e) {
      this.imgNaturalSize.width = e.target.naturalWidth;
      this.imgNaturalSize.height = e.target.naturalHeight;
      console.log("图片原始尺寸：", this.imgNaturalSize);
    },
    async forcedProductionFN(bool) {
      if (bool) this.isForcedProduction = true;
    },
  },
  mounted() {
    this.imgHeight = window.screen.height + "px";
    this.systemSetting = this.$dataStore.get("setting");

    bus.$on("busEmit", (v) => {
      let { type, value, size, productMark } = v;

      switch (type) {
        case "completeMessage":
          this.logList.unshift(`订单：${value}生产完成`);
          this.localeData = getOrderInfoMap();
          break;
        case "completeFail":
          this.logList.unshift(`订单：${value}已打印完成，未生产完成`);
          this.localeData = getOrderInfoMap();
          break;
        case "grid":
          this.row = value.row;
          this.col = value.col;

          if (
            this.detail &&
            this.detail.mssWidth &&
            this.detail.adjustable &&
            this.detail.mssHeight
          ) {
            this.detail.designImageSize = {
              width: this.detail.mssWidth,
              height: this.detail.mssHeight,
            };
          }

          break;
        case "index":
          this.indexChange(value);
          break;
        case "bg":
          this.changeImageColor(value, (res) => {
            this.img = res;
          });
          break;
        case "updateSystemSetting":
          this.systemSetting = this.$dataStore.get("setting");

          break;
        case "uploadImage":
          this.addFile(value, () => {
            this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
          });
          break;
        case "sendFile":
          this.detail.designImageSize = size;

          this.imgList = [];
          this.selectImgList = [];
          this.selectIndex = -1;
          this.productMark = productMark || this.productMark;
          if (value.length > 0) {
            this.selectImgList = value;

            if (this.newDesktopDevice == 3) {
              if (v.faceType) {
                this.faceType = v.faceType;
                const index = this.selectImgList.findIndex(
                  (el) => el.title === v.faceType,
                );
                this.selectImgIndex = index;
              }
            } else {
              this.selectImgIndex = 0;
            }

            if (this.selectImgIndex != -1) {
              this.getBackFile(
                {
                  files: [value[this.selectImgIndex]],
                  size: this.detail.designImageSize || null,
                },
                () => {
                  this.imgHistoryList.push(
                    JSON.parse(JSON.stringify(this.imgList)),
                  );
                },
              );
            }
          }
          this.localeData = getOrderInfoMap();
          break;
        default:
          break;
      }
    });

    document.addEventListener("keyup", this.keyup);
    this.$nextTick(() => {
      this.listenUpload();
    });
    document.addEventListener("click", this.handleClick);
  },
  beforeDestroy() {
    // 销毁组件时移除事件监听器
    document.removeEventListener("click", this.handleClick);
    if (this.deviceStoreWatcher) {
      this.deviceStoreWatcher(); // 调用 electron-store 监听器返回的函数，移除监听
    }
  },
};
</script>

<template>
  <div class="page-main">
    <img-setting
      ref="imgSetting"
      @ev="ev"
      @change="formChange"
      :item="returnItem"
      @close="close"
      :newDesktopDevice="newDesktopDevice"
    >
      <template #content>
        <div class="information-content">
          <div class="main">
            <div class="boxTitle">效果图</div>
            <div
              v-if="detail?.imageAry?.length"
              class="boxImg"
              style="width: 100%;"
            >
              <div
                v-for="(img, index) in detail.imageAry"
                :key="index"
                class="img-item"
              >
                <img :src="img.url" />
                <div v-if="img.title && img.title.length < 2" class="imgTitle">
                  {{ img.title }}
                </div>
              </div>
            </div>
            <el-empty v-else description="效果图为空"></el-empty>
          </div>
          <div class="main">
            <div
              class="boxTitle"
              style="display: flex;justify-content: space-between;align-items: center;padding: 0 10px;"
            >
              <div>素材图</div>
              <div v-if="selectImgList.length && newDesktopDevice != 3">
                <el-button
                  type="primary"
                  size="small"
                  style="margin: 5px;"
                  @click="clearImagecCache"
                  >清除图片缓存
                </el-button>
                <el-button
                  type="primary"
                  size="small"
                  style="margin: 5px;"
                  @click="downloadImg"
                  >下载原素材
                </el-button>
                <el-button
                  type="primary"
                  size="small"
                  style="margin: 5px;"
                  @click="cutImgFn"
                  >裁切
                </el-button>
              </div>
            </div>
            <div
              v-if="selectImgList.length"
              class="boxImg"
              style="width: 100%;"
            >
              <div
                v-for="(img, i) in selectImgList"
                :key="i"
                class="img-item"
                :class="{ borderStyle: i === selectImgIndex }"
                @click.stop.prevent="
                  newDesktopDevice !== 3 && selectImg(img, i)
                "
              >
                <img v-if="img.productionFile" :src="img.productionFile" />
                <div v-if="img.title && img.title.length < 2" class="imgTitle">
                  {{ img.title }}
                </div>
                <div
                  v-if="img.power && img.title != faceType"
                  class="printTitle"
                >
                  已打印
                </div>
              </div>
            </div>
            <el-empty v-else description="素材图为空"></el-empty>
          </div>
        </div>
        <div class="product-information">
          <div class="title">
            生产单信息
          </div>
          <div class="div-content">
            <div :title="detail.podProductionNo" class="div-item">
              <div class="item-label">生产单号：</div>
              <div class="item-value">
                {{ detail.factorySubOrderNumber }}
                <div
                  style="margin-left: 5px"
                  v-if="detail.podProductionNo"
                  :style="{
                    color: detail.customizedQuantity > 1 ? 'red' : '#67C23A',
                  }"
                >
                  {{ detail.customizedQuantity > 1 ? "多" : "单" }}
                </div>
              </div>
            </div>
            <div :title="detail.factorySubOrderNumber" class="div-item">
              <div class="item-label">工厂单号：</div>
              <div class="item-value">{{ detail.factorySubOrderNumber }}</div>
            </div>
            <div :title="detail.processName" class="div-item">
              <div class="item-label">生产工艺：</div>
              <div class="item-value">{{ detail.processName }}</div>
            </div>
            <div :title="detail.baseSku" class="div-item">
              <div class="item-label">基版：</div>
              <div class="item-value">{{ detail.baseSku }}</div>
            </div>
            <div :title="detail.size" class="div-item">
              <div class="item-label">尺寸：</div>
              <div class="item-value">{{ detail.size }}</div>
            </div>
            <div :title="detail.variantSku" class="div-item">
              <div class="item-label">变体SKU：</div>
              <div class="item-value">{{ detail.variantSku }}</div>
            </div>
            <div :title="detail.num" class="div-item">
              <div class="item-label">数量：</div>
              <div class="item-value">{{ detail.num }}</div>
            </div>
            <div :title="detail.supplierItemNo" class="div-item">
              <div class="item-label">货号：</div>
              <div class="item-value">{{ detail.supplierItemNo }}</div>
            </div>
            <div :title="detail.color" class="div-item">
              <div class="item-label">颜色：</div>
              <div class="item-value">
                {{ detail.baseSku ? detail.baseSku.split("_")[1] : null }}
              </div>
            </div>

            <div :title="detail.factoryCode" class="div-item">
              <div class="item-label">工厂：</div>
              <div class="item-value">{{ detail.factoryCode }}</div>
            </div>
            <div
              :title="detail.shopNumber"
              class="div-item"
              style="flex: 100%;"
            >
              <div>
                店铺单号：
              </div>
              <div>
                {{ detail.shopNumber }}
              </div>
            </div>
            <div
              :title="detail.createTime"
              class="div-item"
              style="flex: 100%;"
            >
              <div>创建时间：</div>
              <div>{{ detail.createTime }}</div>
            </div>
            <div
              :title="detail.startStockingTime"
              class="div-item"
              style="flex: 100%;"
            >
              <div>
                生产确认时间：
              </div>
              <div>{{ detail.startStockingTime }}</div>
            </div>
            <div
              v-if="detail.mssWidth && detail.mssHeight"
              class="div-item"
              style="flex: 100%;"
            >
              <div>模规格：</div>

              <div class="item-value">
                mm:&nbsp;(&nbsp; w:
                {{ detail.mssWidth }}
                &nbsp; h:
                {{ detail.mssHeight }}&nbsp;)
              </div>
            </div>
            <div
              v-if="detail.mssWidth && detail.mssHeight"
              class="div-item"
              style="flex: 100%;"
            >
              <div style="opacity: 0;">模规格：</div>
              <div class="item-value">
                inch:&nbsp;(&nbsp;w:
                {{ (Number(detail.mssWidth) / 25.4).toFixed(1) }}
                &nbsp;h:
                {{ (Number(detail.mssHeight) / 25.4).toFixed(1) }}&nbsp;)
              </div>
            </div>
          </div>
        </div>
        <div
          class="main"
          v-show="newDesktopDevice == 3"
          style="margin-top: 20px;"
        >
          <el-form>
            <el-form-item label="下载位置1">
              <div style="display: flex; ">
                <el-input
                  :title="downloadLocation1"
                  v-model="downloadLocation1"
                  :disabled="true"
                  style="flex: 1;margin-right: 5px;"
                ></el-input>
                <el-button @click="changeLocation('downloadLocation1')"
                  >浏览</el-button
                >
              </div>
            </el-form-item>
            <el-form-item label="下载位置2">
              <div style="display: flex; ">
                <el-input
                  :title="downloadLocation2"
                  v-model="downloadLocation2"
                  :disabled="true"
                  style="flex: 1;margin-right: 5px;"
                ></el-input>
                <el-button @click="changeLocation('downloadLocation2')"
                  >浏览</el-button
                >
              </div>
            </el-form-item>
          </el-form>
        </div>
      </template>
    </img-setting>
    <div
      @click="newDesktopDevice != 3 && outsideClick"
      class="main-bg"
      :style="{ 'background-color': !isView ? '#77797a' : '#fff' }"
    >
      <div class="container">
        <div style="width: 100%;height: 100%; " id="content">
          <div v-if="isView" id="img">
            <div
              id="line"
              style="background-color: transparent;overflow: hidden"
              :style="{ left: leftPosition, top: topPosition }"
            >
              <div
                class="sucaitu vieWsucaitu"
                :style="{ width: '100%', height: '100%' }"
              >
                <vue-drag-resize-rotate
                  :w="item.w / getWHproportion(WHproportion)"
                  class-name="my-drag-resize-rotate"
                  :prevent-deactivation="false"
                  :h="item.h / getWHproportion(WHproportion)"
                  :x="item.x / getWHproportion(WHproportion)"
                  :z="item.zIndex / getWHproportion(WHproportion)"
                  :aspectRatio="false"
                  :isActive="false"
                  :y="item.y / getWHproportion(WHproportion)"
                  v-for="(item, index) in imgList"
                  :key="index"
                  :draggable="false"
                  :resizable="false"
                  :rotatable="false"
                  :angle="item.r"
                  style="pointer-events: auto;cursor: default"
                >
                  <div
                    ref="sucaitu-img"
                    :style="{ zIndex: item.zIndex }"
                    class="sucaitu-img img"
                    style="cursor: default"
                  >
                    <img
                      crossOrigin="anonymous"
                      :src="item.url"
                      :id="item.fileName + '_' + index"
                      alt=""
                      style="width: 100%;height: 100%"
                      class="sucaitu-img"
                    />
                  </div>
                </vue-drag-resize-rotate>
              </div>
              <div
                :class="{ 'no-border-grid': systemSetting.gridShow !== 1 }"
                :style="{
                  width: gridWH.row * 30 + 'px',
                  height: gridWH.col * 30 + 'px',
                }"
                class="grid"
                style="border-style:dashed"
              ></div>
            </div>
            <div style="width: 1040px;height: 100%;"></div>
            <!-- <img class="template-img" draggable="false" :src="img" alt="" /> -->
          </div>
          <div
            v-else
            style="width: 100%;height: 100%;background-color:#77797a ;position: relative;"
          >
            <div :style="{ background: gridBg }" id="line" class="boxShaow">
              <!-- <div
            class="sucaitu"
            :style="{ width: gridWH.w + 'px', height: gridWH.h + 'px' }"
          > -->

              <div class="left-bg-color">
                <el-color-picker
                  color-format="hex"
                  :predefine="predefineColors"
                  size="small"
                  v-model="gridBg"
                ></el-color-picker>
              </div>
              <div
                class="sucaitu"
                id="editView"
                :style="{ width: '100%', height: '100%' }"
              >
                <vue-drag-resize-rotate
                  :w="item.w"
                  class-name="my-drag-resize-rotate"
                  :prevent-deactivation="false"
                  :h="item.h"
                  :x="item.x"
                  :z="item.zIndex"
                  :aspectRatio="true"
                  :isActive="index === selectIndex"
                  :y="item.y"
                  v-for="(item, index) in imgList"
                  :key="index"
                  :draggable="true"
                  :resizable="true"
                  :rotatable="true"
                  @dragstop="(a) => dragStop(a, item)"
                  @resizestop="(a) => resizeStop(a, item)"
                  @rotatestop="(a) => rotating(a, item)"
                  @drag="getDrag"
                  :angle="item.r"
                >
                  <div
                    ref="sucaituImg"
                    :class="{ active: index === selectIndex }"
                    :style="{ zIndex: item.zIndex }"
                    class="sucaitu-img img element"
                  >
                    <img
                      ref="targetImg"
                      crossOrigin="anonymous"
                      :src="item.url"
                      id="imgBox"
                      alt=""
                      style="width: 100%;height: 100%"
                      class="sucaitu-img"
                      @load="onImageLoad"
                    />

                    <i
                      @click="delImg(index)"
                      v-if="index === selectIndex"
                      class=" close el-icon-close"
                    ></i>
                    <div
                      v-if="index === selectIndex"
                      class="control-point control-rotator"
                    ></div>
                  </div>
                </vue-drag-resize-rotate>

                <canvas ref="pixelCanvas" style="display: none"></canvas>
              </div>

              <div
                :class="{ 'no-border-grid': systemSetting.gridShow !== 1 }"
                :style="{
                  width: gridWH.w + 'px',
                  height: gridWH.h + 'px',
                }"
                class="grid"
                id="grid"
              >
                <div
                  :style="{
                    height: gridSpacing.h,
                    lineHeight: gridSpacing.h,
                  }"
                  class="grid-row"
                  v-for="it in 100"
                  :key="it"
                >
                  <div
                    :style="{ width: gridSpacing.w, height: gridSpacing.h }"
                    class="grid-col"
                    v-for="it in 100"
                    :key="it"
                  ></div>
                </div>
              </div>
            </div>
          </div>
          <div
            class="print-tip"
            :style="{ left: isView ? '' : '22%' }"
            v-if="
              productMark == 'custom_part' &&
                selectImgList.length &&
                !isOver &&
                !isMove &&
                !selectImgList.some((el) => el.isCut) &&
                newDesktopDevice !== 3
            "
          >
            <b style="color:green">该单无需拖动设计，直接打印</b>
          </div>
          <div
            class="print-tip"
            :style="{ left: isView ? '' : '6%' }"
            v-if="
              productMark == 'custom_part' &&
                selectImgList.length &&
                !selectImgList.some((el) => el.isCut) &&
                isOver &&
                newDesktopDevice !== 3
            "
          >
            <b style="color:red"
              >素材效果已经超出台版范围，请更换更大台版或和客户协调沟通</b
            >
          </div>
          <div
            class="print-tip"
            :style="{ left: isView ? '' : '22%' }"
            v-if="
              newDesktopDevice == 3 &&
                productMark == 'custom_part' &&
                detail.productMark
            "
          >
            <!-- <b
              style="color:red"
              v-if="!selectImgList.length && !isForcedProduction"
              >该生产单素材已经被强制调整适配台版大小，请关注</b
            > -->
            <b style="color:green" v-if="selectImgList.length"
              >该单无需拖动设计，直接打印</b
            >
          </div>
        </div>

        <img
          class="template-img"
          draggable="false"
          :src="img"
          alt=""
          style="position: absolute;width: 1000px;left: 3%;height: 100%;"
          :style="{ 'z-index': isView ? '0' : '-1' }"
        />
      </div>
      <div v-if="newDesktopDevice != 3">
        <print-dialog
          :isDisabled="isView"
          :visible="printDialogShow"
          :imgList="imgList"
          :byPlatenSize="gridWH.v"
        >
          <i
            @click="changePrintDialogShow"
            :class="
              !printDialogShow ? 'el-icon-arrow-left' : 'el-icon-arrow-right'
            "
          ></i>
        </print-dialog>
      </div>
      <div v-else>
        <div class="box">
          <div class="logBox">
            <el-tabs
              v-model="activeName"
              type="card"
              @tab-click="tabHandleClick"
            >
              <el-tab-pane label="操作日志" name="1" class="tabBox">
                <div
                  v-for="(value, index) in logList"
                  :key="index"
                  v-html="formatLog(value)"
                ></div>
              </el-tab-pane>
              <el-tab-pane label="本地数据" name="2" class="tabBox">
                <div
                  v-for="(mapValue, mapKey) in localeData"
                  :key="mapKey"
                  class="localItem"
                >
                  <!-- ① 展开/收起切换 + 直接展示 Map 原始 key -->
                  <div class="json-toggle" @click="toggleExpand(mapKey)">
                    {{ expandStatus[mapKey] ? "▼" : "▶" }} 订单标识：{{
                      mapValue[0]
                    }}
                  </div>

                  <!-- ② 展开后展示 Map Value，保留原有 json-pre 样式 -->
                  <pre v-if="expandStatus[mapKey]" class="json-pre"
                    >{{ formatJson(mapValue) }}
        </pre
                  >
                </div></el-tab-pane
              >
            </el-tabs>
          </div>
          <div
            v-if="activeName == 1"
            style="padding: 10px; border-top: 1px solid #ececec"
          >
            <el-button
              type="primary"
              size="small"
              @click="
                () => {
                  logList = [];
                }
              "
              >清空日志</el-button
            >
          </div>
          <div v-else style="padding: 10px; border-top: 1px solid #ececec">
            <el-button type="primary" size="small" @click="clearLocalFn"
              >清空本地数据</el-button
            >
          </div>
        </div>
      </div>
    </div>
    <el-dialog
      title="警告：无法直接生产"
      :visible.sync="dialogVisible"
      width="30%"
    >
      <div>
        素材效果已经超出台版范围，无法直接打印。请更换打印设
        备，或者进行强制生产
      </div>

      <div>注:“自动强制生产”会让每次生产都强制生产</div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button @click="forcedProductionFN">强制生产</el-button>
        <el-button @click="forcedProductionFN(true)" style="color: red;"
          >自动强制生产</el-button
        >
      </span>
    </el-dialog>
  </div>
</template>

<style lang="less" scoped>
.print-tip {
  position: absolute;
  bottom: 60px;
  font-size: 24px;
  left: 25%;
}

.page-main {
  display: flex;
  flex: 1;
  flex-shrink: 0;
  overflow: hidden;
  box-sizing: border-box;
}

.main-bg {
  flex: 1;
  // height: 100%;
  display: flex;

  // align-items: center;
  // justify-content: center;
}

#line {
  position: absolute;
  // z-index: 2;

  left: 5%;
  top: 50%;
  transform: translate(0, -50%);
  background-color: #f0f2f6;
}

.grid {
  // border: 1px solid gray;
  overflow: hidden;

  .grid-row {
    .grid-col {
      box-sizing: border-box;

      display: inline-block;
      border: 1px solid gray;
      border-right: none;
      border-bottom: none;
    }
  }
}

.grid-row {
  width: 100%;
  overflow: hidden;
  height: 10px;
  line-height: 10px;
  white-space: nowrap;

  &:nth-of-type(1) {
    .grid-col {
      border-top: none !important;
    }
  }

  &:nth-last-of-type(1) {
    .grid-col {
      border-bottom: none !important;
    }
  }

  .grid-col {
    &:nth-of-type(1) {
      border-left: none !important;
    }
  }
}

#img {
  // position: absolute;
  // z-index: 1;
  // left: 130px;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  // width: auto;
  position: absolute;
  z-index: 2;
  left: 5%;

  img {
    pointer-events: none;
    width: auto;
    height: 100%;
  }
}

.container {
  display: flex;
  width: 100%;
  height: 100%;
  // justify-content: center;
  // align-items: center;
  position: relative;
}

.sucaitu {
  // position: absolute;
  // z-index: 0;
  width: 100%;
  //display: flex;
  //justify-content: center;
  //align-items: center;
  height: 100%;

  img {
    width: 100%;
    height: 100%;
  }

  .element {
    // position: relative;
  }

  // #imgBox {
  //   img {
  //     transition: clip-path 0.1s ease-in;
  //   }
  // }
  .close {
    position: absolute;
    top: -11px;
    right: -12px;
    color: white;
    z-index: 1000;
    width: 20px;
    cursor: pointer;
    height: 20px;
    background: red;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
  }

  .img {
    height: fit-content;
    width: 100%;
    height: 100%;
    cursor: move;
    border: 1px dashed transparent;
  }
}

.select-img {
  border: 1px solid #ececec;
  width: 100%;
  overflow: auto;
  height: calc(100% - 251px);
  padding: 10px;
  box-sizing: border-box;
}

img {
  user-select: none;
  user-drag: none;
}

::v-deep .active,
.active {
  border-color: #66b1ff !important;
}

.select-img-index {
  box-sizing: border-box;
  border-color: #409eff !important;
}

.showImg {
  // max-height: 194px !important;
  // text-align: center;
  // width: auto !important;
  width: 100%;
  height: auto;
}

.sucaitu-img {
  position: relative;
}

.no-border-grid {
  border-color: transparent !important;

  * {
    border-color: transparent !important;
  }
}

.el-checkbox-group {
  height: 100%;
  // border-top: 1px solid #ececec;
  margin-bottom: 25px;

  ::v-deep .el-checkbox {
    height: 100%;
    width: 100%;
    margin: 0;
    box-sizing: border-box;
    border: 1px solid #ffffff;
    margin: 5px;
    // margin-bottom: 5px;
    .el-checkbox__input {
      position: absolute;
      top: 5px;
      left: 5px;
    }

    .el-checkbox__label {
      width: 100%;
      padding: 0;
      height: 100%;
      background-color: #e3e3e3;
    }
  }
}

.imgchecked {
  border: 1px solid #409eff !important;
}
</style>
<style lang="less" scoped>
.el-upload {
  height: 100%;
}

.drr-stick {
  z-index: 9999;
}

.drr-stick-tr {
  z-index: -1 !important;
}

.my-drag-resize-rotate {
  border-color: transparent;
}

.handle-rot::before,
.handle-rot::after {
  display: none;
}

.information-content {
  border: 1px solid #ececec;
  // border-top: none;
  width: 100%;
  box-sizing: border-box;
  .main {
    border-bottom: 1px solid #ececec;
    min-height: 250px;
    &:last-child {
      border: none;
    }
    .boxTitle {
      padding: 5px 10px;

      font-weight: 700;
      font-size: 20px;
    }
    .boxImg {
      width: 100%;
      display: flex;
      // padding: 5px;
      box-sizing: border-box;
      overflow-x: auto;
      .img-item {
        flex: 50%;
        position: relative;
        // overflow: hidden;
        padding: 5px;
        box-sizing: border-box;
        background: #ececec;
        display: inline-block;
        cursor: pointer;
        box-sizing: border-box;
        text-align: center;
        line-height: 1;
        // &:first-child {
        //   margin-right: 5px;
        // }
        img {
          width: auto;
          height: auto;

          max-height: 190px;
          max-width: 220px;
        }

        .imgTitle {
          font-weight: 700;
          font-size: 18px;
          position: absolute;
          top: 8px;
          left: 8px;
          width: 25px;
          height: 25px;
          color: #fff;
          text-align: center;
          border-radius: 50%;
          background-color: #409eff;
          line-height: 25px;
        }
        .printTitle {
          font-weight: 700;
          font-size: 18px;
          position: absolute;
          top: 8px;
          right: 8px;
          width: 65px;
          height: 25px;
          border: 3px solid red;
          color: red;
          line-height: 25px;
        }
      }
    }
    .boxImg > * {
      margin: 5px;
    }
    .effectPic {
      .img {
        width: 100%;
      }
    }
  }

  .pic-title {
    text-align: center;
  }
}

.product-information {
  border: 1px solid #ececec;
  border-top: none;

  .title {
    padding: 5px 10px;
  }

  .div-content {
    padding: 0 10px;
    display: flex;
    flex-wrap: wrap;

    .div-item {
      display: flex;
      flex: 50%;
      font-size: 12px;
      margin-bottom: 5px;

      .item-label {
        flex: 1;
        text-align: right;
      }

      .item-value {
        flex: 36%;
      }
    }
  }
}

.title {
  padding: 5px 10px;
  font-size: 20px;
  font-weight: 700;
}

.border-row {
  border-top: 1px solid #ececec;
  // border-bottom: 1px solid #ececec;
  display: flex;
  width: 100%;
  height: 100%;
  // align-items: center;
}

.full-width {
  width: 100%;
}

.text-center {
  text-align: center;
  display: flex;
  align-items: center;
  justify-content: center;
}

.border-col {
  border-left: 1px solid #ececec;
  border-right: 1px solid #ececec;
}

.boxShaow {
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.2), 0 0 15px rgba(0, 0, 0, 0.14),
    0 0 20px rgba(0, 0, 0, 0.12);
  position: relative;

  .left-bg-color {
    position: absolute;
    left: -45px;
  }
}

.vieWsucaitu {
  .active::before {
    display: none;
  }

  //::v-deep .drr:hover:before {
  //  outline: none;
  //}
}

// ::v-deep.el-table thead {
//   color: black;
// }
.fixed-border {
  position: fixed;
  z-index: 69;
}

.crop-canvas {
  position: absolute;
  top: 1px;
  left: 1px;
  pointer-events: none; /* 允许穿透操作 */
  z-index: 2; /* 确保在元素上方 */
}
::v-deep.el-empty {
  padding-top: 0;
  padding-bottom: 25px;
  .el-empty__image {
    width: 100px !important;
  }
}
.box {
  position: relative;
  width: 420px;
  height: 100%;
  background-color: #fff;
  display: flex;
  justify-content: space-between;
  flex-direction: column;
  // padding-bottom: 10px;
  box-sizing: border-box;
  z-index: 99;
  .el-tabs {
    height: 100%;
    ::v-deep .el-tabs__content {
      height: calc(100% - 60px);
      overflow-y: auto;
    }
  }

  .logBox {
    flex: 1;
    height: 100%;

    .tabBox {
      padding: 0 10px;
      font-size: 12px;
      height: 100%;
      .localItem {
        margin-bottom: 10px;
      }
      .json-pre {
        white-space: pre-wrap; /* 关键：允许换行 */
        word-break: break-word; /* 允许在单词内换行 */
        word-wrap: break-word; /* 旧版属性，为了兼容性 */
        overflow-wrap: break-word; /* 现代标准 */
        font-family: "Courier New", Courier, monospace;
        font-size: 12px;
        line-height: 1.4;
        margin: 0;

        // max-height: 300px; /* 限制最大高度 */
        // overflow-y: auto; /* 超过最大高度时垂直滚动 */
        padding: 8px;
        background: #f5f5f5;
        border-radius: 3px;
        border: 1px solid #e8e8e8;
      }
    }
  }
}
.status-complete {
  color: #85ce61;
}
.logBox {
  flex: 1;
  height: 100%;

  .tabBox {
    padding: 0 10px;
    font-size: 12px;
    height: 100%;

    .localItem {
      margin-bottom: 10px;
    }

    // 新增：展开/收起切换按钮
    .json-toggle {
      cursor: pointer;
      font-size: 12px;
      margin: 4px 0;
      color: #1890ff;
      user-select: none;
    }

    .json-toggle:hover {
      color: #40a9ff;
    }

    // 新增：JSON 内容容器
    .json-content {
      margin-left: 20px;
      padding-left: 10px;
      border-left: 1px dashed #e8e8e8;
    }

    // 新增：嵌套内容缩进
    .nested {
      margin-left: 20px;
    }

    // 新增：JSON 项和值
    .json-view {
      font-family: "Courier New", Courier, monospace;
    }

    .json-item {
      margin: 2px 0;
    }

    .json-value {
      font-size: 12px;
      color: #666;
      margin: 4px 0;
    }

    // 保留你原有的 json-pre 样式（可复用）
    .json-pre,
    .json-view {
      white-space: pre-wrap; /* 关键：允许换行 */
      word-break: break-word; /* 允许在单词内换行 */
      word-wrap: break-word; /* 旧版属性，为了兼容性 */
      overflow-wrap: break-word; /* 现代标准 */
      font-family: "Courier New", Courier, monospace;
      font-size: 12px;
      line-height: 1.4;
      margin: 0;
      padding: 8px;
      background: #f5f5f5;
      border-radius: 3px;
      border: 1px solid #e8e8e8;
    }
  }
}
.borderStyle {
  border: 3px solid #409eff;
}
</style>
