吉安感知网项目-前端
罗广辉
2026-01-20 f9329e44d49ae4296695227112558d5f9c52c167
Merge remote-tracking branch 'origin/master'
7 files modified
1 files added
216 ■■■■ changed files
applications/drone-command/src/assets/images/dataCockpit/legend/drone.png patch | view | raw | blame | history
applications/drone-command/src/assets/images/dataCockpit/map/drone.png patch | view | raw | blame | history
applications/drone-command/src/styles/common/cockpit.scss 17 ●●●●● patch | view | raw | blame | history
applications/drone-command/src/views/basicManage/deviceStock/FormDiaLog.vue 4 ●●●● patch | view | raw | blame | history
applications/drone-command/src/views/recordManage/historyTracks/TrajectoryDiaLog.vue 17 ●●●● patch | view | raw | blame | history
applications/task-work-order/src/views/orderView/orderDataManage/supplyAdd/ApplyViewDialog.vue 162 ●●●● patch | view | raw | blame | history
applications/task-work-order/src/views/orderView/orderDataManage/supplyAdd/index.vue 4 ●●●● patch | view | raw | blame | history
packages/utils/common/index.js 12 ●●●●● patch | view | raw | blame | history
applications/drone-command/src/assets/images/dataCockpit/legend/drone.png

applications/drone-command/src/assets/images/dataCockpit/map/drone.png
applications/drone-command/src/styles/common/cockpit.scss
@@ -1079,6 +1079,7 @@
    transform: translate(-50%, -50%);
    .el-dialog__header {
        padding-bottom: 20px;
        position: relative;
        span {
@@ -1111,7 +1112,7 @@
            padding: 0 10px;
            .detail-title {
                line-height: 40px;
                margin-bottom: 20px;
                font-family: Source Han Sans CN, Source Han Sans CN;
                font-weight: 500;
                font-size: 16px;
@@ -1123,7 +1124,7 @@
            .el-row {
                .el-col {
                    margin-bottom: 0;
                    margin-bottom: 20px;
                    display: flex;
                    align-items: center;
@@ -1133,7 +1134,6 @@
                        font-weight: 500;
                        font-size: 14px;
                        color: #D4D5D7;
                        line-height: 40px;
                        text-align: right;
                        font-style: normal;
                        text-transform: none;
@@ -1145,7 +1145,6 @@
                        font-weight: 400;
                        font-size: 14px;
                        color: #9E9EBA;
                        line-height: 40px;
                        text-align: left;
                        font-style: normal;
                        text-transform: none;
@@ -1165,6 +1164,11 @@
        }
        .dialog-form {
            h3 {
                margin: 0;
                margin-bottom: 20px;
            }
            .detail-title {
                line-height: 40px;
                font-family: Source Han Sans CN, Source Han Sans CN;
@@ -1433,7 +1437,7 @@
                    align-items: center;
                    justify-content: space-between;
                    padding-left: 16px;
                    padding-bottom: 16px;
                    padding-bottom: 20px;
                    font-family: Source Han Sans CN, Source Han Sans CN;
                    font-weight: 400;
                    font-size: 18px;
@@ -1469,7 +1473,7 @@
                    .el-row {
                        .el-col {
                            margin-bottom: 0;
                            margin-bottom: 20px;
                            display: flex;
                            align-items: center;
@@ -1479,7 +1483,6 @@
                                font-weight: 500;
                                font-size: 14px;
                                color: #D4D5D7;
                                line-height: 40px;
                                text-align: right;
                                font-style: normal;
                                text-transform: none;
applications/drone-command/src/views/basicManage/deviceStock/FormDiaLog.vue
@@ -55,8 +55,8 @@
                <div class="command-table-content">
                    <el-table class="command-table" :data="list">
                        <el-table-column type="index" width="60" label="序号" />
                        <el-table-column prop="charger" label="用户" />
                        <el-table-column prop="contactPhone" label="电话" />
                        <el-table-column prop="charger" label="负责人" />
                        <el-table-column prop="contactPhone" label="联系电话" />
                        <el-table-column prop="outTarget" label="出库去向" />
                        <el-table-column prop="outTime" label="出库时间" />
                        <el-table-column prop="purpose" label="用途" />
applications/drone-command/src/views/recordManage/historyTracks/TrajectoryDiaLog.vue
@@ -73,6 +73,7 @@
import * as Cesium from 'cesium'
import { flyVisual } from '@/utils/cesium/mapUtil'
import { ArrowLineMaterialProperty } from '@/utils/cesium/Material'
import droneIcon from '@/assets/images/dataCockpit/map/drone.png'
const initForm = () => ({
    droneName: '',
@@ -127,6 +128,7 @@
// 渲染航线
function drawFlightPath() {
    const positions = list.value.map(p => degreesToC3(p))
    if (!positions.length) return
    droneLineEntity && geometricSource.entities.remove(droneLineEntity)
    droneLineEntity = geometricSource.entities.add({
        polyline: {
@@ -134,6 +136,16 @@
            positions: positions,
            material: arrowLineMaterialProperty,
            clampToGround: false,
        },
    })
    startDroneEntity && geometricSource.entities.remove(startDroneEntity)
    startDroneEntity = geometricSource.entities.add({
        position: positions[0],
        billboard: {
            image: droneIcon,
            width: 40,
            height: 40,
            verticalOrigin: Cesium.VerticalOrigin.CENTER,
        },
    })
    viewer.flyTo(droneLineEntity, { duration: 0 })
@@ -146,6 +158,7 @@
    viewer = null
    geometricSource = null
    droneLineEntity = null
    startDroneEntity = null
}
function getRowClassName({ row }) {
@@ -154,7 +167,7 @@
    return row?.isAlarm === 1 ? 'alarm-row' : ''
}
let viewer, geometricSource, droneLineEntity
let viewer, geometricSource, droneLineEntity, startDroneEntity
function initMap() {
    if (viewer) return
    const publicCesiumInstance = new PublicCesium({
@@ -189,7 +202,7 @@
<style scoped lang="scss">
:deep(.alarm-row) {
    background: #2B2B4C !important;
    td {
        background-color: transparent !important;
    }
applications/task-work-order/src/views/orderView/orderDataManage/supplyAdd/ApplyViewDialog.vue
@@ -86,36 +86,33 @@
                    <div class="label">数据上传</div>
                    <div class="upload-container">
                        <el-upload
                            ref="uploadRef"
                            :auto-upload="false"
                            :limit="1"
                            :on-change="handleFileChange"
                            :on-remove="handleFileRemove"
                            :before-upload="beforeFileUpload"
                            :file-list="fileList"
                            accept=".zip,.rar,.7z,.tar,.gz"
                            class="upload-demo"
                        >
                        :http-request="handleHttpRequest"
                        :limit="3"
                        :on-success="handleUploadSuccess"
                        :on-error="handleUploadError"
                        :on-remove="handleFileRemove"
                        :before-upload="beforeFileUpload"
                        :file-list="fileList"
                        accept=".zip,.rar,.7z,.tar,.gz"
                        class="upload-demo"
                    >
                            <template #trigger>
                                <el-button type="primary">选择文件</el-button>
                            </template>
                            <template #tip>
                                <div class="el-upload__tip">请上传压缩文件 (.zip/.rar/.7z/.tar/.gz)</div>
                                <div class="el-upload__tip">支持上传 (.zip/.rar/.7z/.tar/.gz)格式文件</div>
                            </template>
                        </el-upload>
                        <el-button type="success" :disabled="!selectedFile" @click="handleUpload" style="margin-top: 10px">
                            上传文件
                        </el-button>
                        <!-- 已上传文件列表 -->
                        <div v-if="uploadedFiles.length > 0" class="uploaded-files">
                            <h4>已上传文件:</h4>
                            <div v-for="(file, index) in uploadedFiles" :key="index" class="file-item">
                                <span>{{ file.originalName }}</span>
                                <el-button type="text" @click="viewFile(file)" style="margin-left: 10px">查看</el-button>
                                <el-button type="text" @click="downloadFile(file)" style="margin-left: 5px">下载</el-button>
                            </div>
                        </div>
<!--                        <div v-if="uploadedFiles.length > 0" class="uploaded-files">-->
<!--                            <h4>已上传文件:</h4>-->
<!--                            <div v-for="(file, index) in uploadedFiles" :key="index" class="file-item">-->
<!--                                <span>{{ file.originalName }}</span>-->
<!--                                <el-button type="text" @click="viewFile(file)" style="margin-left: 10px">查看</el-button>-->
<!--                                <el-button type="text" @click="downloadFile(file)" style="margin-left: 5px">下载</el-button>-->
<!--                            </div>-->
<!--                        </div>-->
                    </div>
                </div>
                <div v-if="detailDemandStatus === '2'">
@@ -175,27 +172,45 @@
const demandId = ref('')
const visible = defineModel() // 弹框显隐
const formData = ref({}) // 表单数据
const uploadRef = ref() // 上传组件引用
const selectedFile = ref(null) // 选择的文件
const fileList = ref([]) // 上传文件列表
const uploadedFiles = ref([]) // 已上传文件列表
const uploadLoading = ref(false) // 上传加载状态
const responseData = ref([])
const responseData = ref(null)
// 自定义上传请求函数
const handleHttpRequest = async (options) => {
    try {
        // 创建FormData对象
        const formData = new FormData()
        formData.append('file', options.file)
        // 调用导入的API函数
        const response = await putFileAttachApi(formData)
        console.log('response',response)
        if (response.data && response.data.success) {
            // 调用上传成功的回调
            options.onSuccess(response)
        } else {
            // 调用上传失败的回调
            options.onError(new Error(response.data?.msg || '文件上传失败'))
        }
    } catch (error) {
        // 调用上传失败的回调
        options.onError(error)
        console.error('文件上传失败:', error)
    }
}
// 拒绝申请弹框控制
const rejectionDialogVisible = ref(false) // 拒绝申请弹框显隐
const tableData = ref([]) // 附件表格数据
// 文件选择变化
const handleFileChange = (file, fileList) => {
    if (fileList.length > 0) {
        selectedFile.value = file.raw
    } else {
        selectedFile.value = null
    }
}
// 文件移除
const handleFileRemove = () => {
    selectedFile.value = null
const handleFileRemove = (file, fileList) => {
    // 从已上传文件列表中移除对应文件
    if (file.response && file.response.attachId) {
        uploadedFiles.value = uploadedFiles.value.filter(item => item.attachId !== file.response.attachId)
    }
    // 清空响应数据
    if (responseData.value && responseData.value.attachId === file.response?.attachId) {
        responseData.value = null
    }
}
// 上传前验证
@@ -218,57 +233,28 @@
    return true
}
// 处理文件上传
const handleUpload = async () => {
    if (!selectedFile.value) {
        ElMessage.warning('请先选择文件')
        return
    }
// 上传成功处理函数
const handleUploadSuccess = (response, file, fileList) => {
    // 添加更严格的检查,确保response不是undefined
    if (response && response?.data && response?.data?.success) {
        const fileData = response.data.data
        console.log('成功数据', fileData)
        responseData.value = fileData
        // 添加到已上传文件列表
        uploadedFiles.value.push({
            name: fileData.name,
            originalName: fileData.originalName,
            link: fileData.link,
            attachId: fileData.attachId,
        })
    // 再次验证文件类型
    if (!beforeFileUpload(selectedFile.value)) {
        return
    }
        ElMessage.success('文件上传成功!')
    }
}
    try {
        uploadLoading.value = true
        // 创建FormData对象
        const formData = new FormData()
        formData.append('file', selectedFile.value)
        // 调用上传接口
        const response = await putFileAttachApi(formData)
        if (response.data && response.data.success) {
            const fileData = response.data.data
            console.log('成功数据', fileData)
            responseData.value = fileData
            // 添加到已上传文件列表
            uploadedFiles.value.push({
                name: fileData.name,
                originalName: fileData.originalName,
                link: fileData.link,
                attachId: fileData.attachId,
            })
            ElMessage.success('文件上传成功!')
            // 清空上传列表
            uploadRef.value.clearFiles()
            selectedFile.value = null
            // 这里可以将附件ID保存到表单数据中,供后续提交使用
            // formData.value.attachmentId = fileData.attachId
        } else {
            ElMessage.error(response.data?.msg || '文件上传失败')
        }
    } catch (error) {
        console.error('文件上传失败:', error)
        ElMessage.error('文件上传失败,请重试')
    } finally {
        uploadLoading.value = false
    }
// 上传失败处理函数
const handleUploadError = (error, file, fileList) => {
    ElMessage.error(error?.message || '文件上传失败,请重试')
}
// 查看文件
@@ -412,7 +398,7 @@
// 拒绝申请
const rejectTheApplication = () => {
    if (responseData.value.length === 0) {
    if (!responseData.value) {
        return ElMessage.warning('请上传数据')
    }
    // 打开拒绝申请弹框
@@ -436,7 +422,7 @@
}
// 审核通过
const approvedByTheReview = () => {
    if (responseData.value.length === 0) {
    if (!responseData.value) {
        return ElMessage.warning('请上传数据')
    }
    const id = [responseData.value.attachId]
applications/task-work-order/src/views/orderView/orderDataManage/supplyAdd/index.vue
@@ -54,7 +54,7 @@
                        </template>
                    </el-table-column>
                    <el-table-column prop="contactPerson" show-overflow-tooltip label="需求联系人" />
                    <el-table-column prop="contactPhone" show-overflow-tooltip label="需求联系人电话" />
                    <el-table-column prop="contactPhone" show-overflow-tooltip width="120" label="需求联系人电话" />
                    <el-table-column prop="contactEmail" show-overflow-tooltip label="需求邮箱" />
                    <el-table-column prop="demandStatus" show-overflow-tooltip label="需求状态">
                        <template v-slot="{ row }">
@@ -76,7 +76,7 @@
                    <el-table-column prop="responsibleDeptName" show-overflow-tooltip label="责任部门" />
                    <el-table-column prop="dataSource" show-overflow-tooltip label="数据来源依据" />
                    <el-table-column prop="demandInfo" show-overflow-tooltip label="需求信息项" />
                    <el-table-column label="操作" class-name="operation-btns">
                    <el-table-column label="操作" class-name="operation-btns" width="130">
                        <template v-slot="{ row }">
                    <el-link @click="openForm('view', row)">查看</el-link>
                    <!-- 只对非审批状态显示编辑和删除按钮 -->
packages/utils/common/index.js
@@ -1,3 +1,13 @@
/*
 * @Author       : yuan
 * @Date         : 2026-01-20 17:01:20
 * @LastEditors  : yuan
 * @LastEditTime : 2026-01-20 17:20:21
 * @FilePath     : \packages\utils\common\index.js
 * @Description  :
 * Copyright 2026 OBKoro1, All Rights Reserved.
 * 2026-01-20 17:01:20
 */
export function fieldRules(required,max) {
// export function fieldRules({ required = true, isSelect = false, max = 50,type = 'string' }) {
    const trigger = ['blur', 'change']
@@ -14,7 +24,7 @@
export function getDictLabel(value, dictList) {
    return dictList.filter(item => value.includes(item.dictKey)).map(item => item.dictValue).join(',')
    return dictList.filter(item => String(value).includes(String(item.dictKey))).map(item => item.dictValue).join(',')
}
export function blobDownload(res) {