pms-front/src/views/project/demandManage/components/SidebarTree.vue

449 lines
10 KiB
Vue
Raw Blame History

<template>
<div
class="sidebarTree"
:class="{
hidenLeft: !showFlag,
}"
>
<i
class="el-icon-arrow-right"
style="font-size: 24px; margin-top: 20px; cursor: pointer"
v-show="!showFlag"
@click.stop="changeShow()"
></i>
<!-- 树形菜单 -->
<div class="treeTitle">版本列表</div>
<div class="topBox" v-show="showFlag">
<div class="topText" @click.stop="changeOpen">
<i v-show="openFlag" class="el-icon-caret-bottom"></i>
<i v-show="!openFlag" class="el-icon-caret-right"></i>
<img src="@/assets/demand/list.png" />
<span>全部版本</span>
</div>
<div class="topBtn">
<i
class="el-icon-plus"
@click.stop="dialogVisible = true"
style="font-size: 20px"
></i>
<i
class="el-icon-arrow-left"
style="font-size: 20px"
@click.stop="changeShow()"
></i>
</div>
</div>
<el-tree
v-show="showFlag"
:data="treeData"
:props="defaultProps"
:default-expanded-keys="defaultExpend"
node-key="nodeId"
class="tree"
ref="treeRef"
@node-click="handleNodeClick"
:expand-on-click-node="false"
>
<template #default="{ node, data }">
<div
class="treeNode"
@mousemove="data.hover = true"
@mouseout="data.hover = false"
>
<!-- 展开/收起图标 -->
<!-- 节点图标 -->
<img
v-if="data.type == 0 && data.nodeId === selectedId"
src="@/assets/demand/treeIcon.png"
class="nodeIcon"
/>
<img
v-if="data.type == 0 && data.nodeId !== selectedId"
src="@/assets/demand/treeIcon1.png"
class="nodeIcon"
/>
<!-- 节点文本 -->
<el-tooltip
class="item"
effect="light"
:content="data.title"
placement="top"
:disabled="data.title.length > 8 ? false : true"
>
<div
:class="[
'nodeLabel',
data.nodeId === selectedId ? 'selected' : '',
]"
>
{{ data.title }}
</div>
</el-tooltip>
<!-- 右侧数字标记 -->
<span
v-if="data.type == 0 && !data.hover"
:class="[
'count',
data.nodeId === selectedId ? 'selectedCount' : '',
]"
>
{{ data.childrenList.length }}
</span>
<el-dropdown
v-show="data.type == 0 && data.hover"
trigger="click"
placement="bottom"
@command="
(val) => {
changeRow(val, data);
}
"
>
<i class="el-icon-more" style="font-size: 20px"></i>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="add">新建需求</el-dropdown-item>
<el-dropdown-item command="edit">编辑</el-dropdown-item>
<el-dropdown-item command="del" style="color: #dd242a"
>删除</el-dropdown-item
>
</el-dropdown-menu>
</el-dropdown>
<!-- 右侧操作图标 -->
<img
v-if="data.actionIcon"
:src="data.actionIcon"
class="actionIcon"
/>
</div>
</template>
</el-tree>
<el-dialog title="添加版本号" :visible.sync="dialogVisible" width="30%">
<el-form>
<el-form-item label="版本号">
<el-input v-model="demandData.name"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="confirmAddNode">确定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { demandApi } from "@/utils/api";
export default {
name: "SidebarTree",
props: {
projectId: {
type: String,
default: "",
},
},
data() {
return {
selectedId: "",
treeData: [],
defaultProps: {
children: "childrenList",
label: "title",
},
dialogVisible: false,
demandData: {
name: "",
},
openFlag: false,
showFlag: true,
defaultExpend: [],
};
},
methods: {
handleNodeClick(data) {
this.selectedId = data.nodeId;
this.changeVersion(data);
},
getVersionTree(defaultId) {
demandApi
.getVersionTree({
projectId: this.projectId,
demandStatusList: [],
})
.then((res) => {
if (!res.data.length) {
this.treeData = [];
return;
}
res.data = res.data.map((ele) => {
ele.nodeId = ele.id + "_" + ele.type;
ele.childrenList.map((item) => {
item.nodeId = item.id + "_" + item.type;
});
ele.hover = false;
return ele;
});
this.initTableData(defaultId, res.data);
this.treeData = res.data;
});
},
changeVersion(data) {
if (!data) {
data = {
id: this.projectId,
type: 2,
};
}
this.$emit("changeVersion", data);
},
initTableData(defaultId, tableList) {
if (defaultId && defaultId != "all") {
let searchNode = {};
this.defaultExpend = [defaultId];
searchNode = tableList.find((ele) => ele.nodeId == defaultId);
this.changeVersion(searchNode);
this.selectedId = this.defaultExpend[0];
} else if (defaultId == "all") {
this.selectedId = "";
this.changeVersion({
id: this.projectId,
type: 2,
});
} else {
this.defaultExpend = [tableList[0].nodeId];
this.selectedId = this.defaultExpend[0];
this.setVersionList(tableList.filter((ele) => ele.type == 0));
this.changeVersion(
tableList.find((ele) => ele.nodeId == this.defaultExpend[0])
);
}
},
setVersionList(data) {
this.$emit("setVersionList", data);
},
confirmAddNode() {
if (!this.demandData.name) {
this.$message({
message: "请填写版本号",
type: "warning",
});
return;
}
if (this.demandData.name.length > 10) {
this.$message({
message: "版本号限制10个字符",
type: "warning",
});
return;
}
let param = {
projectId: this.projectId,
versionNumber: this.demandData.name,
};
if (this.demandData.id) {
param.id = this.demandData.id;
demandApi.editVersion(param).then((res) => {
this.resetAdd(0);
});
} else {
demandApi.addVersion(param).then((res) => {
this.resetAdd(1);
});
}
},
resetAdd(add) {
this.$message({
message: add ? "添加成功" : "修改成功",
type: "success",
});
this.dialogVisible = false;
this.demandData.name = "";
this.demandData.id = "";
this.getVersionTree();
},
editDemand(data) {
this.demandData = {
name: data.title,
id: data.id,
};
this.dialogVisible = true;
},
delVersion(data) {
this.$confirm("此操作将永久删除该版本号, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
demandApi.delVersion(data.id).then((res) => {
this.$message({
type: "success",
message: "删除成功!",
});
this.getVersionTree();
});
})
.catch(() => {});
},
changeOpen() {
this.openFlag = !this.openFlag;
if (this.openFlag) {
this.defaultExpend = this.treeData.map((ele) => ele.nodeId);
} else {
this.defaultExpend = [];
}
this.getVersionTree("all");
},
changeShow() {
this.showFlag = !this.showFlag;
},
changeRow(type, row) {
if (type == "add") {
this.$emit("addDemand");
} else if (type == "edit") {
this.editDemand(row);
} else if (type == "del") {
this.delVersion(row);
}
},
},
watch: {
projectId(newVal) {
this.$nextTick(() => {
this.getVersionTree();
});
},
},
};
</script>
<style scoped lang="scss">
.sidebarTree {
width: 100%;
max-width: 300px;
min-height: 100vh;
background-color: inherit;
padding-left: 20px;
}
.hidenLeft {
width: 40px;
}
.tree {
width: 100%;
height: 100%;
}
.treeNode {
display: flex;
align-items: center;
width: 100%;
height: 48px;
padding: 0 20px;
border-radius: 2px;
}
::v-deep .el-tree-node__children {
padding-left: 15px !important;
}
.expandIcon {
width: 10px;
height: 10px;
margin-right: 15px;
}
.nodeIcon {
width: 18px;
height: 18px;
margin-right: 15px;
}
.nodeLabel {
flex: 1;
font-family: "PingFang SC";
font-size: 16px;
font-weight: 600;
line-height: 36px;
color: #333;
max-width: 160px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
padding-right: 20px;
}
.nodeLabel.selected {
color: #4096ff;
}
.count {
font-family: "PingFang SC";
font-size: 16px;
font-weight: 600;
line-height: 26px;
color: #999;
margin-right: 15px;
}
.selectedCount {
color: #4096ff;
}
.actionIcon {
width: 18px;
height: 18px;
}
.treeTitle {
padding: 20px;
font-size: 18px;
font-weight: 600;
color: #333;
}
/* */
// .treeNode:has(.selected) {
// background-color: #f6faff;
// }
::v-deep .el-tree-node {
min-height: 42px;
.el-tree-node__content {
height: 42px;
}
:not(.is-leaf.el-tree-node__expand-icon) {
font-size: 16px;
// color: #333;
}
}
.topBox {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
margin-bottom: 10px;
.topText {
gap: 15px;
font-size: 16px;
font-weight: 600;
display: flex;
cursor: pointer;
img {
width: 18px;
height: 18px;
}
}
.topBtn {
display: flex;
gap: 10px;
i {
cursor: pointer;
}
}
}
// /* <EFBFBD><EFBFBD> */
// .treeNode:hover {
// background-color: #f5f5f5;
// }
</style>