123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328 |
- <!-- 左侧文件夹结构 -->
- <template>
- <div class="left-folder" v-loading="loading">
- <el-scrollbar style="height: 100%">
- <el-row style="padding: 6px 12px; margin-top: 10px">
- <span style="font-size: 12px; color: #646c73">文件夹</span>
- <i class="el-icon-plus add-folder-icon" title="添加文件夹" @click="handleShowAddFolder"></i>
- </el-row>
- <ul class="folder-list">
- <li class="folder-item" style="cursor: auto" v-show="showAddFolder">
- <el-input
- style="width: 157px"
- ref="folderName"
- size="small"
- clearable
- v-model="folderName"
- @keyup.native.enter="handleClickAddFolder"
- placeholder="请输入文件夹名称"
- ></el-input>
- <i class="el-icon-refresh-left revoke-icon" title="撤销" @click="handleRevokeAddFolder"></i>
- <i class="el-icon-check confirm-icon" title="确认" @click="handleClickAddFolder"></i>
- </li>
- <li
- class="folder-item"
- :class="{ 'folder-select': folder.checked }"
- v-for="folder in folderData"
- :key="folder.id"
- :title="folder.name"
- @contextmenu.prevent="openMenu($event, folder)"
- @click="handleCheckFolder(folder.id)"
- >
- <span v-show="!folder.showInput" class="folder-item-text">{{ folder.name }}</span>
- <!-- <el-badge is-dot class="folder-item-number">103</el-badge> -->
- <el-input
- v-show="folder.showInput"
- style="width: 157px"
- :ref="`folderName${folder.id}`"
- size="small"
- clearable
- v-model="folder.updateName"
- @keyup.native.enter="handleUpdateFolderName(folder)"
- placeholder="请输入文件夹名称"
- ></el-input>
- <i
- v-show="folder.showInput"
- class="el-icon-refresh-left revoke-icon"
- title="撤销"
- @click.stop="handleRevokeUpdateFolder(folder)"
- ></i>
- <i v-show="folder.showInput" class="el-icon-check confirm-icon" title="确认" @click.stop="handleUpdateFolderName(folder)"></i>
- </li>
- <!-- 右键菜单部分 -->
- <ul v-show="visible" :style="{ left: left + 'px', top: top + 'px' }" class="contextmenu">
- <li @click="showUpdateFolderName">重命名</li>
- <li @click="handleDeleteFolder">删除文件夹</li>
- </ul>
- </ul>
- </el-scrollbar>
- </div>
- </template>
- <script>
- import { folderCreate, folderDelete, folderUpdate, folderQuery } from "@/api/labsl";
- export default {
- data() {
- return {
- showAddFolder: false,
- loading: false,
- folderName: "未命名文件夹",
- folderData: [],
- visible: false,
- top: 0,
- left: 0,
- rightClickFolder: null,
- };
- },
- created() {
- this.getFolderData();
- },
- methods: {
- // 获取文件夹数据
- async getFolderData(folderId) {
- this.loading = true;
- const params = {
- pageNumber: 1,
- pageSize: 1000,
- orders: "name asc, createTime desc"
- }
- const res = await folderQuery(params);
- this.folderData = res.content.map((folder) => {
- folder.updateName = folder.name;
- folder.checked = false;
- folder.showInput = false;
- return folder;
- });
- // 如果参数传入文件夹,则选中对应的文件夹,否则默认选中第一个文件夹
- if (folderId) {
- this.handleCheckFolder(folderId);
- } else {
- this.handleCheckFolder(this.folderData[0].id);
- }
- this.loading = false;
- },
- // 点击添加文件夹icon打开弹窗
- handleShowAddFolder() {
- this.showAddFolder = true;
- this.$nextTick(() => {
- this.$refs.folderName.focus();
- });
- },
- // 创建文件夹
- async handleClickAddFolder() {
- if (!this.folderName) {
- this.$message({ showClose: true, message: "请输入文件夹名称!" });
- } else if (
- this.folderData.find((folder) => {
- return folder.name === this.folderName;
- })
- ) {
- this.$message({ showClose: true, message: "您输入的文件夹已存在!" });
- } else {
- const res = await folderCreate({ content: [{ name: this.folderName }] });
- if (res.result === "success" && res.entityList.length) {
- res.entityList.forEach((item) => {
- this.folderData.unshift({
- id: item.id,
- name: item.name,
- updateName: item.name,
- checked: false,
- showInput: false,
- });
- });
- this.$message.success("添加文件夹成功!");
- this.handleRevokeAddFolder();
- this.handleCheckFolder(res.entityList[res.entityList.length - 1].id);
- } else {
- this.$message.error(res.message);
- }
- }
- },
- // 撤销添加文件夹
- handleRevokeAddFolder() {
- // 初始化添加文件夹状态
- this.showAddFolder = false;
- this.folderName = "未命名文件夹";
- },
- // 点击文件夹
- handleCheckFolder(folderId) {
- this.folderData.forEach((item) => {
- if (item.id === folderId) {
- item.checked = true;
- this.$emit("changeFolder", item);
- } else {
- item.checked = false;
- }
- });
- },
- // 右键文件夹
- openMenu(e, folder) {
- this.visible = true;
- this.top = e.pageY;
- this.left = e.pageX;
- this.rightClickFolder = folder;
- },
- // 关闭右键菜单
- closeMenu() {
- this.visible = false;
- },
- // 显示要修改的文件夹输入框
- showUpdateFolderName() {
- if (this.rightClickFolder) {
- this.rightClickFolder.showInput = true;
- this.$nextTick(() => {
- this.$refs[`folderName${this.rightClickFolder.id}`][0].focus();
- });
- }
- },
- // 文件夹重命名
- async handleUpdateFolderName(folder) {
- if (!folder.updateName) {
- this.$message({ showClose: true, message: "请输入文件夹名称!" });
- } else if (
- this.folderData.find((item) => {
- return item.name === folder.updateName;
- })
- ) {
- this.$message({ showClose: true, message: "您输入的文件夹已存在!" });
- } else {
- const res = await folderUpdate({
- content: [
- {
- id: folder.id,
- name: folder.updateName,
- },
- ],
- });
- if (res.result === "success") {
- folder.name = folder.updateName;
- this.$message.success("文件夹重命名成功!");
- folder.showInput = false;
- } else {
- this.$message.error(res.message);
- }
- }
- },
- // 撤销重命名
- handleRevokeUpdateFolder(folder) {
- folder.updateName = folder.name;
- folder.showInput = false;
- },
- // 删除文件夹
- handleDeleteFolder() {
- if (this.rightClickFolder) {
- this.$confirm("此操作将永久删除该文件夹, 是否继续?", "提示", {
- confirmButtonText: "确定",
- cancelButtonText: "取消",
- type: "warning",
- }).then(async () => {
- const res = await folderDelete([{ id: this.rightClickFolder.id }]);
- if (res.result === "success") {
- this.folderData.splice(
- this.folderData.findIndex((item) => {
- return item.id === this.rightClickFolder.id;
- }),
- 1
- );
- this.$message.success("删除成功!");
- } else {
- this.$message.error(res.message);
- }
- });
- }
- },
- },
- watch: {
- // 监听 visible,来触发关闭右键菜单,调用关闭菜单的方法
- visible(value) {
- if (value) {
- document.body.addEventListener("click", this.closeMenu);
- } else {
- document.body.removeEventListener("click", this.closeMenu);
- }
- },
- },
- };
- </script>
- <style lang="less" scoped>
- .left-folder {
- background: #f7f9fa;
- color: #1f2429;
- width: 100%;
- padding: 0 8px;
- height: 100%;
- padding-left: 6px;
- .add-folder-icon {
- float: right;
- margin-top: 3px;
- cursor: pointer;
- }
- .add-folder-icon:hover {
- color: #0091ff;
- }
- .folder-list {
- width: 100%;
- .folder-item {
- width: 100%;
- cursor: pointer;
- height: 40px;
- line-height: 40px;
- padding: 0 12px;
- .folder-item-text {
- display: inline-block;
- width: calc(100% - 35px);
- overflow: hidden;
- white-space: nowrap;
- text-overflow: ellipsis;
- }
- .folder-item-number {
- height: 18px;
- line-height: 18px;
- font-size: 12px;
- color: #646c73;
- margin-top: 11px;
- float: right;
- }
- .revoke-icon {
- cursor: pointer;
- margin-left: 8px;
- }
- .confirm-icon {
- cursor: pointer;
- color: #67c23a;
- margin-left: 8px;
- }
- }
- .folder-select {
- color: #0091ff;
- background-color: #e1f2ff;
- border-radius: 4px;
- }
- .folder-item:hover {
- color: #0091ff;
- background-color: #e1f2ff;
- border-radius: 4px;
- }
- .contextmenu {
- width: 120px;
- background: #fff;
- z-index: 3000;
- position: fixed;
- list-style-type: none;
- padding: 8px 0;
- border-radius: 4px;
- font-size: 12px;
- box-shadow: 0px 2px 10px 0px rgba(31, 35, 41, 0.1);
- li {
- margin: 0;
- padding: 8px 12px;
- cursor: pointer;
- }
- li:hover {
- color: #0091ff;
- background: #e1f2ff;
- }
- }
- }
- }
- </style>
|