Commit 6454a6d3 authored by tianhongyang's avatar tianhongyang

feat(详情头部组件封装):

parent 290a27cd
...@@ -3,8 +3,8 @@ ...@@ -3,8 +3,8 @@
<!-- tab列表 --> <!-- tab列表 -->
<div class="dsk-tab-items-container"> <div class="dsk-tab-items-container">
<div class="dsk-tab-items-container-inner"> <div class="dsk-tab-items-container-inner">
<div class="dsk-tab-item" v-for="item of tabs" :key="item.id" :class="{'tab-current' : item.value == currentValue}" @click="tabChoose(item)"> <div class="dsk-tab-item" v-for="item of tabs" :key="item.id" :class="{'tab-current' : item.value == currentValue}">
<div class="dsk-tab-item-name">{{item.name}}</div> <div class="dsk-tab-item-name" @click="tabChoose(item)">{{item.name}}</div>
</div> </div>
<!-- 下滑条 --> <!-- 下滑条 -->
<div class="dsk-tab-sliding-bar" v-if="tabs.length" :style="{width : `${silidingBarWidth}px`,transform : `translateX(${silidingBarLeft}px)`}"> <div class="dsk-tab-sliding-bar" v-if="tabs.length" :style="{width : `${silidingBarWidth}px`,transform : `translateX(${silidingBarLeft}px)`}">
......
...@@ -1030,3 +1030,28 @@ export function generateRandomLowerCaseLetter() { ...@@ -1030,3 +1030,28 @@ export function generateRandomLowerCaseLetter() {
const randomIndex = Math.floor(Math.random() * alphabet.length); const randomIndex = Math.floor(Math.random() * alphabet.length);
return alphabet[randomIndex]; return alphabet[randomIndex];
} }
/**
* 获取直系祖先到本身组成的数组
* @param {object} data
* @param {string | number} targetId
* @param {string} idKey
* @param {Array<any>} ancestors
* @returns
*/
export function findAncestors(data, targetId, idKey = "uid", childrenKey = "children", ancestors = []) {
if (data[idKey] === targetId) {
return [...ancestors, data]; // 找到目标节点,将其添加到祖先数组中并返回
}
if (data[childrenKey]?.length) {
for (const child of data[childrenKey]) {
const result = findAncestors(child, targetId, idKey, childrenKey, [...ancestors, data]); // 递归调用,将当前节点添加到祖先数组中
if (result) {
return result; // 如果找到了目标节点,则停止继续遍历并返回结果
}
}
}
return null; // 如果遍历完所有节点都没有找到目标节点,则返回null
}
<template>
<div class="project-bread-crumb-container">
<el-breadcrumb separator-class="el-icon-arrow-right" class="project-bread-crumb-inner">
<!-- 默认展示 -->
<el-breadcrumb-item class="project-bread-crumb-item">
<span @click="$router.push('/projectCostLedger')">项目成本台账</span>
</el-breadcrumb-item>
<!-- 当前模块 -->
<transition name="breadcrumb" mode="out-in">
<el-breadcrumb-item class="project-bread-crumb-item current-bread-brumb-item" v-if="breadCrumb[module]">
<span>{{breadCrumb[module].breadcrumbName}}</span>
</el-breadcrumb-item>
</transition>
<!-- 下级 -->
<transition-group name="breadcrumb" tag="div">
<el-breadcrumb-item class="project-bread-crumb-item" v-for="(item,index) of currentBreadCurmbList" :key="item.path"
:class="{'current-bread-brumb-item' : item.path == current}">
<span @click.stop="item.path == current ? '' : breadClickHandle(item)">{{item.breadcrumbName}}</span>
</el-breadcrumb-item>
</transition-group>
</el-breadcrumb>
</div>
</template>
<script>
import { cloneDeep } from "lodash-es";
import { findAncestors } from "@/utils";
export default {
name: "projectBreadCrumb",
props: {
current: String,
module: String
},
watch: {
current: {
handler(newValue, oldValue) {
this.init(newValue);
}
}
},
data() {
return {
currentBreadCurmbList: [],
breadCrumb: {
// 详情
detail: {
breadcrumbName: "详情",
childrenBreadCrumb: [
{
breadcrumbName: "工程项目信息",
path: "basicEngineeringInformation"
},
{
breadcrumbName: "直接费成本",
path: "directCost"
},
{
breadcrumbName: "工料汇总",
path: "feedSummary"
},
{
breadcrumbName: "措施项目",
path: "measureItem"
},
{
breadcrumbName: "其他项目",
path: "otherItems"
},
{
breadcrumbName: "现场经费",
path: "fieldExpenses"
},
{
breadcrumbName: "成本汇总",
path: "cost"
},
{
breadcrumbName: "盈亏分析对比",
path: "profitAndLoss"
}
]
}
// 缺省配置
}
};
},
//可访问data属性
created() {
this.init(this.current);
},
//计算集
computed: {
},
//方法集
methods: {
init(current) {
if (!current) return;
// 取出当前模块
const _temp = cloneDeep(this.breadCrumb[this.module]);
if (!_temp) return;
this.currentBreadCurmbList = this.createBreadCrumb(current, _temp);
},
createBreadCrumb(current, data) {
let result = findAncestors(data, current, "path", "childrenBreadCrumb");
if (result) {
result = result.filter(item => item.path);
result = result.map(item => {
const _temp = {
breadcrumbName: item.breadcrumbName,
};
if (item.path) _temp["path"] = item.path;
return _temp;
});
return result;
}
;
},
breadClickHandle(item) {
console.log(item);
}
},
}
</script>
<style lang="scss" scoped>
.project-bread-crumb-container {
::v-deep .project-bread-crumb-inner {
.project-bread-crumb-item {
font-size: 14px;
font-weight: 350;
height: 24px;
line-height: 24px;
.el-breadcrumb__inner {
color: rgba(35, 35, 35, 0.4);
cursor: pointer;
&:hover {
color: #0081ff;
}
}
.el-breadcrumb__separator {
color: rgba(35, 35, 35, 0.4);
font-size: 12px;
margin: 0px 4px;
}
&.current-bread-brumb-item {
font-size: 12px;
line-height: 24px;
height: 24px;
.el-breadcrumb__inner {
color: #232323;
cursor: unset;
&:hover {
color: inherit;
}
}
}
}
}
}
</style>
<template>
<div class="project-cost-ledger-detail-header">
<div class="project-cost-ledger-detail-header-inner">
<project-bread-crumb :module="module" :current="current"></project-bread-crumb>
<!-- 项目名称 -->
<div class="project-detail-header-name">宝安中学(集团)初中部改扩建工程施工总承包(二次公告)</div>
<!-- 项目信息 -->
<div class="project-detail-plate">
<div class="detail-plate-item project-code" v-if="isShowProjectCode.includes(current)">
<span class="plate-item-name">项目编码:</span>
<span>AB21131212131</span>
</div>
<div class="detail-plate-item">
<span class="plate-item-name">客户名称:</span>
<span>广联达科技股份有限公司天津分公司天津分公司</span>
</div>
<div class="detail-plate-item">
<span class="plate-item-name">签订单位:</span>
<span>中建一局集团第二建筑有限公司</span>
</div>
</div>
</div>
</div>
</template>
<script>
import ProjectBreadCrumb from "@/views/projectCostLedger/detail/components/ProjectBreadCrumb";
export default {
name: "projectDetailHeader",
props: {
module: String,
current: String
},
components: {
ProjectBreadCrumb
},
data() {
return {
isShowProjectCode: ["basicEngineeringInformation", "directCost", "feedSummary", "cost"]
};
},
//可访问data属性
created() {
},
//计算集
computed: {
},
//方法集
methods: {
},
}
</script>
<style lang="scss" scoped>
.project-cost-ledger-detail-header {
width: 100%;
height: 118px;
overflow: hidden;
background: #fff;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
border-bottom: 1px solid #eeeeee;
padding: 16px;
box-sizing: border-box;
.project-cost-ledger-detail-header-inner {
width: 100%;
height: 100%;
.project-detail-header-name {
line-height: 16px;
margin-top: 16px;
width: 100%;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
font-family: Source Han Sans, Source Han Sans;
font-size: 16px;
color: #232323;
font-weight: bold;
}
.project-detail-plate {
display: flex;
align-items: center;
margin-top: 12px;
.detail-plate-item {
display: flex;
align-items: center;
font-size: 14px;
font-weight: 350;
color: rgba(35, 35, 35, 0.8);
line-height: 18px;
margin-right: 24px;
.plate-item-name {
color: rgba(35, 35, 35, 0.4);
}
}
}
}
}
</style>
<template>
<div class="project-cost-ledger-detail">
<div class="project-cost-ledger-detail-inner">
<project-detail-header :module="module" :current="current"></project-detail-header>
<!-- tab切换栏 -->
<dsk-tab-toggle v-model="current" :tabs="toggleTabs" @tabToggle="tabToggle"></dsk-tab-toggle>
<!-- tab切换组件容器 -->
<div class="project-cost-ledger-detail-module">
<!-- 放入组件 v-if current == ‘xxxx’-->
</div>
</div>
</div>
</template>
<script>
import ProjectDetailHeader from "@/views/projectCostLedger/detail/components/ProjectDetailHeader";
import DskTabToggle from "@/components/DskTabToggle";
import { v4 } from "uuid";
export default {
name: "projectCostLedgerDetail",
components: {
ProjectDetailHeader,
DskTabToggle
},
data() {
return {
current: "basicEngineeringInformation",
module: "detail",
// 详情信息
detailInfo: {},
toggleTabs: [
{
value: "basicEngineeringInformation",
name: "工程项目信息",
id: v4()
},
{
value: "directCost",
name: "直接费成本",
id: v4()
},
{
value: "feedSummary",
name: "工料汇总",
id: v4()
},
{
name: "措施项目",
value: "measureItem",
id: v4()
},
{
name: "其他项目",
value: "otherItems",
id: v4()
},
{
name: "现场经费",
value: "fieldExpenses",
id: v4()
},
{
name: "成本汇总",
value: "cost",
id: v4()
},
{
name: "盈亏分析对比",
value: "profitAndLoss",
id: v4()
}
],
};
},
//可访问data属性
created() {
this.initDetail();
},
//计算集
computed: {
},
//方法集
methods: {
async initDetail() {
try {
} catch (error) {
}
},
// 当前命中的current
tabToggle(value) {
}
},
}
</script>
<style lang="scss" scoped>
.project-cost-ledger-detail {
width: 100%;
height: 100%;
padding: 16px 24px;
box-sizing: border-box;
.project-cost-ledger-detail-inner {
width: 100%;
height: 100%;
::v-deep .dsk-tab-toggle {
height: 57px;
.dsk-tab-items-container .dsk-tab-items-container-inner .dsk-tab-item {
align-items: unset;
padding-top: 20px;
.dsk-tab-item-name {
font-size: 14px;
line-height: 22px;
}
}
.dsk-tab-sliding-bar {
border-radius: 8px;
bottom: 1px;
}
}
.project-cost-ledger-detail-module {
width: 100%;
height: calc(100% - 118px - 57px);
box-sizing: border-box;
overflow: auto;
}
}
}
</style>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment