吉安感知网项目-前端
罗广辉
2026-01-31 d5b9e8f2933849f9d877a5b81bbccb9892ea146f
feat: 进度调整
3 files modified
1 files added
393 ■■■■ changed files
applications/task-work-order/src/views/orderView/orderManage/inspectionRequest/ViewDiaLog.vue 6 ●●●● patch | view | raw | blame | history
applications/task-work-order/src/views/orderView/orderManage/orderManage/FormDiaLog.vue 179 ●●●●● patch | view | raw | blame | history
applications/task-work-order/src/views/orderView/orderManage/orderManage/OrderStepBar.vue 199 ●●●●● patch | view | raw | blame | history
applications/task-work-order/src/views/orderView/orderManage/orderManage/orderManageApi.js 9 ●●●●● patch | view | raw | blame | history
applications/task-work-order/src/views/orderView/orderManage/inspectionRequest/ViewDiaLog.vue
@@ -248,7 +248,7 @@
import { ElMessage } from 'element-plus'
import { fieldRules, flyVisual, getDictLabel } from '@ztzf/utils'
import { gdPatrolTaskRepublish, gdFlyerPageApi, gdPatrolTaskAuditApi } from './inspectionRequestApi'
import { gdWorkOrderFlowListApi, gdWorkOrderPageApi } from '../orderManage/orderManageApi'
import { gdWorkOrderFlowListApi, gdWorkOrderFlowPatrolListApi, gdWorkOrderPageApi } from '../orderManage/orderManageApi'
import { gdManageDeviceListApi } from '../orderManage/gdManageDeviceApi'
import { pxToRem } from '@/utils/rem'
import CommonCesiumMap from '@/components/map-container/common-cesium-map.vue'
@@ -400,9 +400,8 @@
const processList = ref([])
// 加载时间线list
function loadList() {
    gdWorkOrderFlowListApi({ workOrderId: formData.value.id, type: '1' }).then(res => {
    gdWorkOrderFlowPatrolListApi({ workOrderId: formData.value.id, type: '1' }).then(res => {
        processList.value = res.data.data
        console.log(processList.value, 'processList.value')
    })
}
@@ -432,6 +431,7 @@
    }
}
import { ArrowLineMaterialProperty } from '@/utils/cesium/Material'
import OrderStepBar from '@/views/orderView/orderManage/orderManage/OrderStepBar.vue'
let arrowLineMaterialProperty = new ArrowLineMaterialProperty({
    color: new Cesium.Color(128 / 255, 215 / 255, 255 / 255, 1),
    directionColor: new Cesium.Color(1, 1, 1, 1),
applications/task-work-order/src/views/orderView/orderManage/orderManage/FormDiaLog.vue
@@ -10,42 +10,8 @@
    >
        <div class="content" style="display: flex">
            <div class="processBox" v-if="dialogMode !== 'add' && processList.length">
                <div class="timeline-wrapper">
                    <div v-for="(stage, stageIndex) in processList" :key="stageIndex" class="stage-group">
                        <!-- 大节点 Stage Node -->
                        <div class="stage-node">
                            <div class="stage-icon" :class="{ reached: stage.reached }">
                                <el-icon v-if="stage.reached"><Check /></el-icon>
                                <span v-else class="stage-index">{{ stageIndex + 1 }}</span>
                            </div>
                            <span class="stage-name">{{ stage.stageName }}</span>
                        </div>
                        <!-- 小节点 Child Nodes -->
                        <div class="child-list" v-if="stage.child && stage.child.length">
                            <template v-for="(child, childIndex) in stage.child.filter(c => c.reached)">
                                <div v-if="child.reached" :key="childIndex" class="child-node">
                                    <div class="child-left">
                                        <span class="child-status">{{ child.statusName }}</span>
                                    </div>
                                    <div class="child-dot"></div>
                                    <div class="child-right">
                                        <span class="child-operator">{{ child.operator || '-' }}</span>
                                        <span class="child-time">{{ child.createTime || '-' }}</span>
                                    </div>
                                </div>
                            </template>
                        </div>
                        <!-- 连接线 -->
                        <div
                            class="connector-line"
                            v-if="stageIndex < processList.length - 1"
                            :class="{ reached: stage.reached }"
                        ></div>
                    </div>
                </div>
<!--                <div class="detail-title">工单记录</div>-->
                <OrderStepBar :processList="processList" />
            </div>
            <div class="leftBox">
                <div v-if="dialogReadonly">
@@ -311,6 +277,7 @@
import droneIcon from '@/assets/images/orderView/orderManage/drone.png'
import droneActiveIcon from '@/assets/images/orderView/orderManage/droneActive.png'
import { useStore } from 'vuex'
import OrderStepBar from '@/views/orderView/orderManage/orderManage/OrderStepBar.vue'
const store = useStore()
const permission = computed(() => store.state.user.permission)
@@ -707,150 +674,12 @@
    }
    .processBox {
        padding: 24px 16px;
        padding: 12px 16px 24px 16px;
        width: 312px;
        border: 1px solid #e4e4e4;
        border-radius: 8px;
        overflow: auto;
        background: #fff;
        .timeline-wrapper {
            padding-left: 100px;
            position: relative;
        }
        .stage-group {
            position: relative;
        }
        // 大节点 - Stage Node
        .stage-node {
            display: flex;
            align-items: center;
            gap: 12px;
            margin-bottom: 8px;
            .stage-icon {
                width: 28px;
                height: 28px;
                border-radius: 50%;
                background: #e0e0e0;
                display: flex;
                align-items: center;
                justify-content: center;
                color: #fff;
                font-size: 14px;
                font-weight: 600;
                flex-shrink: 0;
                position: relative;
                z-index: 2;
                &.reached {
                    background: #1a1a2e;
                }
                .el-icon {
                    font-size: 16px;
                }
                .stage-index {
                    font-size: 12px;
                }
            }
            .stage-name {
                width: 70px;
                text-align: right;
                position: absolute;
                left: -80px;
                font-family: Roboto, Roboto;
                font-weight: bold;
                font-size: 16px;
                color: rgba(0,0,0,0.85);
            }
        }
        // 小节点 - Child Nodes
        .child-list {
            position: relative;
            left: -52px;
        }
        .child-node {
            display: flex;
            align-items: flex-start;
            position: relative;
            &:last-child::before {
                bottom: 50%;
            }
            .child-left {
                width: 100px;
                flex-shrink: 0;
                text-align: right;
                padding-right: 20px;
                font-family: Source Han Sans CN, Source Han Sans CN;
                font-weight: 400;
                font-size: 14px;
                color: rgba(0,0,0,0.85);
                .child-status {
                    white-space: nowrap;
                }
            }
            .child-dot {
                width: 12px;
                height: 12px;
                border-radius: 50%;
                background: #1a1a2e;
                flex-shrink: 0;
                position: relative;
                z-index: 2;
                margin-top: 4px;
            }
            .child-right {
                flex: 1;
                padding-left: 12px;
                display: flex;
                flex-direction: column;
                gap: 2px;
                .child-operator {
                    font-family: Source Han Sans CN, Source Han Sans CN;
                    font-weight: 400;
                    font-size: 14px;
                    color: rgba(0,0,0,0.85);
                }
                .child-time {
                    white-space: nowrap;
                    font-family: Source Han Sans CN, Source Han Sans CN;
                    font-weight: 400;
                    font-size: 14px;
                    color: rgba(0,0,0,0.45);
                }
            }
        }
        // 连接线
        .connector-line {
            position: absolute;
            left: 13px;
            width: 2px;
            height: 100%;
            background: #e0e0e0;
            top: 28px;
            z-index: 1;
            &.reached {
                background: #1a1a2e;
            }
        }
    }
}
applications/task-work-order/src/views/orderView/orderManage/orderManage/OrderStepBar.vue
New file
@@ -0,0 +1,199 @@
<template>
    <div class="timeline-wrapper">
        <div v-for="(stage, stageIndex) in processList" :key="stageIndex" class="stage-group">
            <!-- 大节点 Stage Node -->
            <div class="stage-node">
                <div class="stage-icon" :class="{ reached: stage.reached }">
                    <el-icon v-if="stage.reached"><Check /></el-icon>
                    <span v-else class="stage-index">{{ stageIndex + 1 }}</span>
                </div>
                <span class="stage-name" :class="{ reached: stage.reached }">{{ stage.stageName }}</span>
            </div>
            <!-- 小节点 Child Nodes -->
            <div class="child-list" v-if="stage?.child?.length && stageIndex !== processList.length-1">
                <template v-for="(child, childIndex) in stage.child.filter(c => c.reached)">
                    <div v-if="child.reached" :key="childIndex" class="child-node">
                        <div class="child-left">
                            <span class="child-status">{{ child.statusName }}</span>
                        </div>
                        <div class="child-dot"></div>
                        <div class="child-right">
                            <span class="child-operator">{{ child.operator || '-' }}</span>
                            <span class="child-time">{{ child.createTime || '-' }}</span>
                        </div>
                    </div>
                </template>
                <!-- 连接线 -->
                <div
                    class="connector-line"
                    v-if="stageIndex < processList.length - 1"
                    :class="{ reached: stage.reached }"
                ></div>
            </div>
        </div>
    </div>
</template>
<script setup>
import { Check } from '@element-plus/icons-vue'
const props = defineProps({
    processList: {
        type: Array,
        default: () => [],
    },
})
</script>
<style scoped lang="scss">
.timeline-wrapper {
    padding-left: 100px;
    position: relative;
    .stage-group {
        position: relative;
    }
    // 大节点 - Stage Node
    .stage-node {
        display: flex;
        align-items: center;
        gap: 12px;
        .stage-icon {
            width: 28px;
            height: 28px;
            border-radius: 50%;
            background: #DBDDE2;
            display: flex;
            align-items: center;
            justify-content: center;
            color: #fff;
            font-size: 14px;
            font-weight: 600;
            flex-shrink: 0;
            position: relative;
            z-index: 2;
            &.reached {
                background: #1a1a2e;
            }
            .el-icon {
                font-size: 16px;
            }
            .stage-index {
                font-size: 12px;
                color: #4E5969;
            }
        }
        .stage-name {
            width: 70px;
            text-align: right;
            position: absolute;
            left: -80px;
            font-family: Roboto, Roboto;
            font-weight: bold;
            font-size: 16px;
            color: rgba(0,0,0,0.45);
            &.reached {
                color: #4C34FF;
            }
        }
    }
    // 小节点 - Child Nodes
    .child-list {
        position: relative;
        left: -92px;
        min-height: 80px;
        // 连接线
        .connector-line {
            position: absolute;
            left: 105px;
            width: 1px;
            height: calc(100% - 5px);
            top: 50%;
            transform: translateY(-50%);
            background: #CCCCCC;
            z-index: 1;
            &.reached {
                background: #4C34FF;
            }
        }
    }
    .child-node {
        display: flex;
        align-items: flex-start;
        position: relative;
        padding: 40px 0;
        &:last-child::before {
            bottom: 50%;
        }
        .child-left {
            width: 100px;
            flex-shrink: 0;
            text-align: right;
            padding-right: 20px;
            font-family: Source Han Sans CN, Source Han Sans CN;
            font-weight: 400;
            font-size: 14px;
            color: rgba(0,0,0,0.85);
            .child-status {
                white-space: nowrap;
            }
        }
        .child-dot {
            width: 12px;
            height: 12px;
            border-radius: 50%;
            background: #1a1a2e;
            flex-shrink: 0;
            position: relative;
            z-index: 2;
            margin-top: 4px;
        }
        .child-right {
            flex: 1;
            padding-left: 12px;
            display: flex;
            flex-direction: column;
            gap: 2px;
            position: relative;
            .child-operator {
                font-family: Source Han Sans CN, Source Han Sans CN;
                font-weight: 400;
                font-size: 14px;
                color: rgba(0,0,0,0.85);
            }
            .child-time {
                position: absolute;
                top: 30px;
                white-space: nowrap;
                font-family: Source Han Sans CN, Source Han Sans CN;
                font-weight: 400;
                font-size: 14px;
                color: rgba(0,0,0,0.45);
            }
        }
    }
}
</style>
applications/task-work-order/src/views/orderView/orderManage/orderManage/orderManageApi.js
@@ -56,3 +56,12 @@
        params:{ descs: 'create_time', ...params },
    })
}
// 分页
export const gdWorkOrderFlowPatrolListApi = params => {
    return request({
        url: `/drone-gd/workOrder/gdWorkOrderFlow/patrolList`,
        method: 'get',
        params:{ descs: 'create_time', ...params },
    })
}