he wei
2025-04-09 850af610b190eeabbd05eba3291fe359775676af
src/components/contextMenu.vue
@@ -15,7 +15,7 @@
          :key="'main_' + idx"
        >
          <div
            :class="['title', {disabled: item.disabled}]"
            :class="['title', { disabled: item.disabled }]"
            @click="itemClick(item)"
            @mouseenter="itemHover(item)"
          >
@@ -26,7 +26,7 @@
            v-show="item.visible && item.children && item.children.length"
          >
            <li
              :class="['sub-li', {disabled: subItem.disabled}]"
              :class="['sub-li', { disabled: subItem.disabled }]"
              v-for="(subItem, index) in item.children"
              :key="'sub_' + index"
              @click="itemClick(subItem)"
@@ -37,12 +37,59 @@
        </li>
      </ul>
    </div>
    <!--  -->
    <el-dialog
      :title="dialogTitle"
      :visible.sync="dialogVisible"
      append-to-body
      width="30%"
    >
      <el-input v-model="stationName" :placeholder="$t('form.inputMsg')"></el-input>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">{{ $t('operate.cancel') }}</el-button>
        <el-button type="primary" @click="stationNameOk">{{ $t('operate.ok') }}</el-button>
      </span>
    </el-dialog>
    <!-- 文件属性 -->
    <el-dialog
      :title="$t('Properties')"
      class="file-info"
      :visible.sync="fileInfoVisible"
      append-to-body
      :close-on-click-modal="false"
      :close-on-press-escape="false"
      :show-close="false"
      width="800px"
    >
      <file-info
        v-if="fileInfoVisible"
        :info="fileData"
        @ok="editOk"
        @cancel="editCancel"
        @quit="quit"
      ></file-info>
    </el-dialog>
  </div>
</template>
<script>
import FileInfo from "@/components/fileInfo";
import i18n from './i18n/contextMenu';
import { createI18nOption } from '@/assets/js/tools/i18n';
const i18nMixin = createI18nOption(i18n);
import {
  addStation,
  addFileInStation,
  updateStation,
  deleteStation,
  delFileFromStation,
  getParamByFileId,
  updateFileParam,
} from "@/apis";
export default {
  name: "ContextMenu",
  mixins: [i18nMixin],
  model: {
    prop: "visible",
    event: "change",
@@ -59,85 +106,111 @@
        return [];
      },
    },
    contextData: {
      type: Object,
      default() {
        return {};
      },
    },
  },
  data() {
    const menuList = [
      {
        id: 0,
        title: "打开文件",
        title: this.$t('OpenFile'),
        method: "openFile",
        disabled: false,
        visible: false,
      },
      {
        id: 1,
        title: "新建",
        title: this.$t('New'),
        disabled: false,
        visible: false,
        children: [
          {
            id: 11,
            title: "新建根文件",
            // method: "openFile",
            title: this.$t('NewRootFile'),
            method: "addRootStation",
            disabled: false,
          },
          {
            id: 12,
            title: "新建子文件",
            // method: "openFile",
            title: this.$t('NewSubFile'),
            method: "addSubStation",
            disabled: false,
          },
        ],
      },
      {
        id: 2,
        title: "添加",
        title: this.$t('New1'),
        disabled: false,
        visible: false,
        children: [
          {
            id: 13,
            title: "指定目录下所有文件",
            title: this.$t('Allfilesinthespecifieddirectory'),
            method: "selectDir",
            disabled: false,
          },
          {
            id: 14,
            title: "单一文件",
            title: this.$t('SingleFile'),
            method: "selectFile",
            disabled: false,
          },
        ],
      },
      {
        id: 3,
        title: "重命名",
        method: "openFile",
        title: this.$t('Rename'),
        method: "rename",
        disabled: false,
        visible: false,
      },
      {
        id: 4,
        title: "删除",
        method: "openFile",
        title: this.$t('Delete'),
        method: "deleteItem",
        disabled: false,
        visible: false,
      },
    ];
    return {
      menuList,
      dialogTitle: "",
      dialogVisible: false,
      stationName: "",
      type: "",
      fileInfoVisible: false,
      fileData: {},
      currFile: {
        name: "",
        // url: "",
        stationId: 0,
        fileId: undefined,
      },
    };
  },
  components: {},
  components: {
    FileInfo,
  },
  watch: {
    visible(n) {
      if(n) {
      if (n) {
        this.initData();
      }
    }
    },
  },
  methods: {
    itemClick(obj) {
      // console.log(obj)
      if (obj.method && "function" == typeof this[obj.method] && !obj.disabled) {
      if (
        obj.method &&
        "function" == typeof this[obj.method] &&
        !obj.disabled
      ) {
        this.close();
        this[obj.method](obj);
      }
@@ -167,16 +240,35 @@
      });
    },
    openFile() {
      // console.log("openfile");
      window.api.send("open-file-dialog");
      let { fileId, label, stationId } = this.contextData;
      getParamByFileId(fileId).then((res) => {
        const { code, data, data2 } = res.data;
        if (code && data) {
          // console.log(data2);
          this.fileData = data2;
          this.currFile.name = label;
          // this.currFile.url = url;
          this.currFile.stationId = stationId;
          this.currFile.fileId = fileId;
          this.fileInfoVisible = true;
        } else {
          this.$message.error(this.$t('FileParsingFailed'));
        }
      });
    },
    initEvents() {
      window.api.receive("selected-file", (path) => {
        console.log(path.filePaths);
        // this.path = path.filePaths;
      window.api.receive("selected-file", (path, data) => {
        if (data && data == "ContextMenu") {
          path = path.filePaths[0];
          this.addFileInStation(path);
        }
      });
      window.api.receive("selected-directory", (path) => {
        console.log(path.filePaths);
      window.api.receive("selected-directory", (path, data) => {
        // console.log('==========', path, data)
        if (data && data == "ContextMenu") {
          path = path.filePaths[0];
          this.addFileInStation(path);
        }
      });
    },
    initData() {
@@ -187,7 +279,219 @@
          item.disabled = this.disabledList.some((val) => val == item.id);
        });
      });
      console.log(this.menuList, this.disabledList, 9090)
      // console.log(this.menuList, this.disabledList, 9090);
    },
    addRootStation() {
      this.dialogTitle = this.$t('NewRootFileName');
      this.stationName = "";
      this.type = "add";
      this.dialogVisible = true;
    },
    addSubStation() {
      this.dialogTitle = this.$t('NewSubFileName');
      this.stationName = "";
      this.type = "add";
      this.dialogVisible = true;
    },
    stationNameOk() {
      if ("" == this.stationName.trim()) {
        this.$message.error(this.$t('Thenamecannotbeblank'));
        return false;
      }
      if (this.type == "add") {
        this.addStation();
      } else if (this.type == "rename") {
        this.renameOk();
      }
    },
    addStation() {
      const { label, parent, level } = this.contextData;
      let params = {};
      const stationName = this.stationName.trim();
      switch (level) {
        case 0:
          params["stationName1"] = label;
          params["stationName2"] = stationName;
          break;
        case 1:
          params["stationName1"] = parent[0];
          params["stationName2"] = label;
          params["stationName3"] = stationName;
          break;
        default:
          params["stationName1"] = stationName;
      }
      addStation(params).then((res) => {
        const { code, data } = res.data;
        if (code && data) {
          this.dialogVisible = false;
          this.$message.success(this.$t('AddSuccessfully'));
          this.reload();
        } else {
          this.$message.error(this.$t('OperationFailed'));
        }
      });
    },
    selectDir() {
      window.api.send("open-directory-dialog", "ContextMenu");
    },
    selectFile() {
      window.api.send("open-file-dialog", "ContextMenu");
    },
    addFileInStation(path) {
      let { label, parent, children } = this.contextData;
      let fileId = children[0] ? children[0].fileId : 0;
      parent = parent.map((v) => v);
      parent.push(label);
      const params = {
        FilePath: path,
        stationName: parent.join("-"),
        fileId
      };
      addFileInStation(params).then((res) => {
        const { code, data, data2 } = res.data;
        if (code && data) {
          // console.log(data2);
          this.reload();
        }
      });
    },
    // 删除站点 或都从站点删除文件
    deleteItem() {
      let { label, parent, level } = this.contextData;
      if (level == 3) {
        this.$confirm(this.$t('Thefilewillberemovedfromthesitewhethertocontinue'), this.$t('Note'), {
          confirmButtonText: this.$t('operate.ok'),
          cancelButtonText: this.$t('operate.cancel'),
          type: "warning",
        }).then(() => {
          this.deleteFile();
        });
      } else {
        this.$confirm(this.$t('Thesitewillbedeletedcontinuetheoperation'), this.$t('Note'), {
          confirmButtonText: this.$t('operate.ok'),
          cancelButtonText: this.$t('operate.cancel'),
          type: "warning",
        }).then(() => {
          this.deleteStation();
        });
      }
    },
    deleteStation() {
      let { label, parent, level } = this.contextData;
      let params = {};
      switch (level) {
        case 0:
          params["stationName1"] = label;
          break;
        case 1:
          params["stationName1"] = parent[0];
          params["stationName2"] = label;
          break;
        case 2:
          params["stationName1"] = parent[0];
          params["stationName2"] = parent[1];
          params["stationName3"] = label;
          break;
      }
      deleteStation(params).then((res) => {
        const { code, data, data2 } = res.data;
        if (code && data) {
          // console.log(data2);
          this.reload();
        }
      });
    },
    deleteFile() {
      let { fileId, parent } = this.contextData;
      parent = parent.map((v) => v);
      let params = {
        stationName: parent.join("-"),
        fileId,
      };
      delFileFromStation(params).then((res) => {
        const { code, data, data2 } = res.data;
        if (code && data) {
          this.$message.success(this.$t('OperationSuccessfully'));
          this.reload();
        } else {
          this.$message.error(this.$t('OperationFailed'));
        }
      });
    },
    // 重命名现只针对台站 (文件是否重命名需要确认需求)
    rename() {
      this.dialogTitle = this.$t('ModifySiteName');
      this.stationName = this.contextData.label;
      this.type = "rename";
      this.dialogVisible = true;
    },
    renameOk() {
      let { label, parent, level } = this.contextData;
      const stationName = this.stationName.trim();
      let params = {};
      switch (level) {
        case 0:
          params["stationName1"] = label;
          params["updateName"] = stationName;
          break;
        case 1:
          params["stationName1"] = parent[0];
          params["stationName2"] = label;
          params["updateName"] = stationName;
          break;
        case 2:
          params["stationName1"] = parent[0];
          params["stationName2"] = parent[1];
          params["stationName3"] = label;
          params["updateName"] = stationName;
          break;
      }
      updateStation(params).then((res) => {
        const { code, data } = res.data;
        if (code && data) {
          this.dialogVisible = false;
          this.$message.success(this.$t('OperationSuccessfully'));
          this.reload();
        } else {
          this.$message.error(this.$t('OperationFailed'));
        }
      });
    },
    reload() {
      this.$emit("reload");
    },
    editOk(data) {
      this.fileInfoVisible = false;
      updateFileParam(this.currFile.stationId, data).then((res) => {
        const { code, data } = res.data;
        if (code && data) {
          this.$message.success(this.$t('ModifySuccessfully'));
        } else {
          this.$message.error(this.$t('ModifyFailed'));
        }
      });
      this.toRes();
    },
    editCancel(data) {
      this.fileInfoVisible = false;
      this.toRes();
    },
    toRes() {
      const { name, url, fileId, stationId } = this.currFile;
      // debugger;
      this.$router.push({
        path: "/result/" + name,
        query: {
          url,
          stationId,
          fileId,
        },
      });
      this.$bus.$emit("checkScroll");
    },
    quit() {
      this.fileInfoVisible = false;
    },
  },
@@ -200,13 +504,15 @@
<style lang="less" scoped>
.context-menu {
  z-index: 1;
  position: absolute;
  background: #fff;
  border: 1px #ccc solid;
  background: #c0c0c0;
  // border: 1px #055AC6 solid;
  border-radius: 4px;
  padding: 4px;
  .contain {
    position: relative;
    background: #c0c0c0;
    z-index: 100;
    .main-ul {
      display: flex;
@@ -215,10 +521,14 @@
        position: relative;
        cursor: pointer;
        flex: 1;
        border: 1px #ccc solid;
        padding: 4px;
        &:hover {
        border: 1px #fff solid;
        .title {
          padding: 4px;
          color: #333;
          background: #f0f0f0;
          &:hover {
            background: #ccc;
          }
        }
        & ~ .main-li {
          margin-top: 2px;
@@ -233,11 +543,12 @@
        top: 0;
        transform: translateX(6px);
        min-width: 10em;
        background: #f0f0f0;
        background: #c0c0c0;
        border-radius: 4px;
        padding: 4px;
        .sub-li {
          border-radius: 4px;
          border: 1px #333 solid;
          border: 1px #fff solid;
          background: #d9dce2;
          &:hover {
            background: #169bd5;
@@ -246,8 +557,8 @@
      }
      .disabled.disabled.disabled {
        cursor: not-allowed;
        color: #aaa;
        background: #ccc;
        color: #eee;
        background: #999;
      }
    }
  }
@@ -261,4 +572,25 @@
    z-index: 99;
  }
}
.file-info {
  :deep(.el-dialog__header) {
    position: relative;
    z-index: 0;
    text-align: center;
    padding-bottom: 16px;
    filter: drop-shadow(0 1px 2px #333);
    &::before {
      content: "";
      position: absolute;
      left: 0;
      top: 0;
      bottom: 0;
      right: 0;
      background: #ccc;
      z-index: -1;
      clip-path: polygon(0 0, 100% 0, 100% 60%, 50% 100%, 0 60%);
      background: linear-gradient(#ccc 10%, #fff 50%, #ccc 90%);
    }
  }
}
</style>