449 lines
10 KiB
Vue
449 lines
10 KiB
Vue
<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>
|