吉安感知网项目-前端
chenyao
2026-01-27 badabf650255dcca75b62b75f90e31c550bf701f
Merge remote-tracking branch 'origin/master'
7 files modified
462 ■■■■■ changed files
applications/drone-command/src/components/map-container/device-map-container.vue 83 ●●●●● patch | view | raw | blame | history
applications/drone-command/src/styles/common/cockpit.scss 187 ●●●●● patch | view | raw | blame | history
applications/drone-command/src/views/areaManage/precinctInfo/FormDiaLog.vue 17 ●●●● patch | view | raw | blame | history
applications/drone-command/src/views/permissionManage/permissionRole/RolePermissionDialog.vue 71 ●●●● patch | view | raw | blame | history
applications/task-work-order/src/page/index/top/index.vue 10 ●●●● patch | view | raw | blame | history
applications/task-work-order/src/views/orderView/organizational/agenciesManagement/FormDiaLog.vue 17 ●●●● patch | view | raw | blame | history
applications/task-work-order/src/views/orderView/organizational/agenciesManagement/index.vue 77 ●●●● patch | view | raw | blame | history
applications/drone-command/src/components/map-container/device-map-container.vue
@@ -14,7 +14,7 @@
                    <div class="panel-title">图层管理</div>
                    <div class="panel-content">
                        <el-tree :data="layerTree" show-checkbox default-expand-all node-key="key"
                        <el-tree class="command-tree" :data="layerTree" show-checkbox default-expand-all node-key="key"
                            :props="layerTreeProps" :default-checked-keys="defaultCheckedKeys" />
                    </div>
                </div>
@@ -1041,87 +1041,6 @@
        flex: 1;
        overflow: auto;
    }
    ::v-deep(.el-tree) {
        background: transparent;
        color: #c3c3dd;
        font-size: 12px;
        .el-tree-node {
            line-height: 30px !important;
            .el-tree-node__content {
                padding-left: 0 !important;
                display: flex;
                align-items: center;
                height: 40px !important;
                line-height: 40px !important;
                border-bottom: 1px solid rgba(70, 70, 100, 0.5);
                box-sizing: border-box;
            }
            .el-tree-node__children {
                .el-tree-node__content {
                    border: none;
                }
            }
            &:focus {
                .el-tree-node__content {
                    background: transparent !important;
                }
            }
        }
    }
}
.layer-panel :deep(.el-tree-node__label) {
    color: #c3c3dd;
}
.layer-panel :deep(.el-tree-node__expand-icon) {
    order: 3;
    margin-left: auto;
}
.layer-panel :deep(.el-tree-node__expand-icon.is-leaf) {
    visibility: hidden;
}
.layer-panel :deep(.el-checkbox) {
    order: 1;
}
.layer-panel :deep(.el-tree-node__label) {
    order: 2;
}
.layer-panel :deep(.el-tree-node__expand-icon:not(.is-leaf) ~ .el-checkbox) {
    display: none;
}
.layer-panel :deep(.el-tree-node__content:hover),
.layer-panel :deep(.el-tree-node__content:focus) {
    background: transparent !important;
}
.layer-panel :deep(.el-tree-node.is-current > .el-tree-node__content) {
    background: transparent !important;
    color: #ffffff;
}
.layer-panel :deep(.el-tree-node.is-current > .el-tree-node__content .el-tree-node__label) {
    color: #ffffff;
}
.layer-panel :deep(.el-checkbox__input.is-checked .el-checkbox__inner) {
    background-color: #023aff;
    border-color: #023aff;
}
.layer-panel :deep(.el-checkbox__inner) {
    background-color: transparent;
    border-color: #a1a3d4;
}
</style>
applications/drone-command/src/styles/common/cockpit.scss
@@ -41,6 +41,87 @@
    height: 40px;
}
.command-tree {
    background: transparent;
    color: #c3c3dd;
    font-size: 12px;
    .el-tree-node {
        line-height: 30px !important;
        .el-tree-node__content {
            padding-left: 0 !important;
            display: flex;
            align-items: center;
            height: 40px !important;
            line-height: 40px !important;
            border-bottom: 1px solid rgba(70, 70, 100, 0.5);
            box-sizing: border-box;
        }
        .el-tree-node__children {
            .el-tree-node__content {
                border: none;
            }
        }
        &:focus {
            .el-tree-node__content {
                background: transparent !important;
            }
        }
    }
    .el-tree-node__label {
        color: #c3c3dd;
    }
    .el-tree-node__expand-icon {
        order: 3;
        margin-left: auto;
    }
    .el-tree-node__expand-icon.is-leaf {
        visibility: hidden;
    }
    .el-checkbox {
        order: 1;
    }
    .el-tree-node__label {
        order: 2;
    }
    .el-tree-node__expand-icon:not(.is-leaf)~.el-checkbox {
        display: none;
    }
    .el-tree-node__content:hover,
    .el-tree-node__content:focus {
        background: transparent !important;
    }
    .el-tree-node.is-current>.el-tree-node__content {
        background: transparent !important;
        color: #ffffff;
    }
    .el-tree-node.is-current>.el-tree-node__content .el-tree-node__label {
        color: #ffffff;
    }
    .el-checkbox__input.is-checked .el-checkbox__inner {
        background-color: #023aff;
        border-color: #023aff;
    }
    .el-checkbox__inner {
        background-color: transparent;
        border-color: #a1a3d4;
    }
}
.command-cascader {
    height: 40px;
@@ -233,7 +314,7 @@
                            .el-time-panel__btn {
                                color: #fff;
                            }
                            .el-time-panel__btn:first-child {
                                color: #86909C;
                            }
@@ -279,7 +360,7 @@
                                .el-time-panel__btn {
                                    color: #fff;
                                }
                                .el-time-panel__btn:first-child {
                                    color: #86909C;
                                }
@@ -329,7 +410,7 @@
                        }
                        // td:hover,
                        // td.current:not(.disabled) {
                        // td.current:not(.disabled{
                        //     background: rgba(60, 121, 202) !important;
                        //     color: white !important;
                        // }
@@ -744,7 +825,7 @@
            }
        }
    }
    .el-input {
        width: 160px;
    }
@@ -1170,7 +1251,7 @@
            text-transform: none;
        }
        & > button {
        &>button {
            width: auto;
            height: auto;
            display: flex;
@@ -1383,6 +1464,102 @@
                        }
                    }
                }
                .address-btn {
                    display: flex;
                    justify-content: flex-start;
                    padding: 0 8px;
                    width: 100%;
                }
            }
        }
        .el-tabs {
            background: transparent;
            border: none;
            .el-tabs__header {
                position: relative;
                background: transparent;
                border: none;
                &::after {
                    content: '';
                    position: absolute;
                    left: 0;
                    bottom: 0;
                    width: 100%;
                    height: 1px;
                    background: #333355;
                }
                .el-tabs__item {
                    position: relative;
                    margin-left: 26px;
                    font-family: Source Code Pro, Source Code Pro;
                    font-weight: 400;
                    font-size: 14px;
                    color: #86909C;
                    text-align: center;
                    font-style: normal;
                    text-transform: none;
                    cursor: pointer;
                    &:first-child {
                        margin-left: 0;
                    }
                    &.is-active {
                        font-weight: normal;
                        color: #FFFFFF;
                    }
                    &::after {
                        content: '';
                        position: absolute;
                        left: 0;
                        bottom: 0;
                        width: 100%;
                        height: 0;
                    }
                    &.is-active::after {
                        height: 3px;
                        background: #284FE3;
                        box-shadow: 0px 3px 2px 0px rgba(15, 89, 255, 0.1), 0px 7px 5px 0px rgba(15, 89, 255, 0.15), 0px 13px 10px 0px rgba(15, 89, 255, 0.18), 0px 22px 18px 0px rgba(15, 89, 255, 0.21), 0px 42px 33px 0px rgba(15, 89, 255, 0.26), 0px 100px 80px 0px rgba(15, 89, 255, 0.36);
                        border-radius: 5px 5px 0px 0px;
                        z-index: 9;
                    }
                }
            }
            .el-tabs__content {
                background: transparent;
                border: none;
                height: 430px;
                overflow-y: auto;
                .el-tab-pane {
                    background: transparent;
                    border: none;
                    .el-tree {
                        background: transparent;
                        border: none;
                    }
                }
            }
            .el-tabs__nav {
                background: transparent;
                border: none;
                .el-tabs__item {
                    background: transparent;
                    border: none;
                }
            }
        }
    }
applications/drone-command/src/views/areaManage/precinctInfo/FormDiaLog.vue
@@ -24,10 +24,17 @@
        <el-form class="dialog-form" v-else ref="formRef" :model="formData" :rules="rules" :disabled="readonly"
            label-width="100px">
            <el-row>
                <el-col :span="12">
                <el-col :span="24">
                    <el-form-item label="派出所名称" prop="stationName">
                        <el-input class="command-input" v-model="formData.stationName" maxlength="50"
                            placeholder="请输入" clearable />
                    </el-form-item>
                </el-col>
                <el-col :span="24">
                    <el-form-item label="位置" prop="longitude">
                        <el-button  class="address-btn" @click="selectLocation">
                            {{ formData.longitude }}, {{ formData.latitude }}, {{ formData.address }}
                        </el-button>
                    </el-form-item>
                </el-col>
                <el-col :span="12">
@@ -40,13 +47,6 @@
                    <el-form-item label="联系方式" prop="contactPhone">
                        <el-input class="command-input" v-model="formData.contactPhone" maxlength="50"
                            placeholder="请输入" clearable />
                    </el-form-item>
                </el-col>
                <el-col :span="24">
                    <el-form-item label="位置" prop="longitude">
                        <el-button @click="selectLocation" style="width: 100%">
                            {{ formData.longitude }}, {{ formData.latitude }}, {{ formData.address }}
                        </el-button>
                    </el-form-item>
                </el-col>
            </el-row>
@@ -290,4 +290,5 @@
defineExpose({ open })
</script>
<style scoped lang="scss">
</style>
applications/drone-command/src/views/permissionManage/permissionRole/RolePermissionDialog.vue
@@ -1,45 +1,17 @@
<template>
    <el-dialog
        class="command-page-view-dialog"
        v-model="visible"
        title="角色权限配置"
        width="620px"
        append-to-body
        :close-on-click-modal="false"
        destroy-on-close
        @closed="handleClosed"
    >
        <el-tabs type="border-card">
            <el-tab-pane label="后台管理">
                <el-tree
                    ref="treeMenu"
                    :data="menuGrantList"
                    show-checkbox
                    node-key="id"
                    :default-checked-keys="menuTreeObj"
                    :props="treeProps"
                />
            </el-tab-pane>
            <el-tab-pane label="移动app">
                <el-tree
                    ref="treeMenuApp"
                    :data="menuGrantListApp"
                    show-checkbox
                    node-key="id"
                    :default-checked-keys="menuTreeObjApp"
                    :props="treeProps"
                />
            </el-tab-pane>
            <el-tab-pane label="新大屏菜单">
                <el-tree
                    ref="treeMenuWebNew"
                    :data="menuGrantListNew"
                    show-checkbox
                    node-key="id"
                    :default-checked-keys="menuTreeObjNew"
                    :props="treeProps"
                />
            </el-tab-pane>
            <el-tab-pane label="无人机管控">
                <el-tree
                    class="command-tree"
                    ref="droneControl"
                    :data="menuGrantListDroneControl"
                    show-checkbox
@@ -50,6 +22,7 @@
            </el-tab-pane>
            <el-tab-pane label="任务工单">
                <el-tree
                    class="command-tree"
                    ref="workRef"
                    :data="menuGrantListWord"
                    show-checkbox
@@ -58,20 +31,21 @@
                    :props="treeProps"
                />
            </el-tab-pane>
            <el-tab-pane label="大屏菜单">
            <el-tab-pane label="移动app">
                <el-tree
                    ref="treeMenuWebOld"
                    :data="menuGrantListOld"
                    class="command-tree"
                    ref="treeMenuApp"
                    :data="menuGrantListApp"
                    show-checkbox
                    node-key="id"
                    :default-checked-keys="menuTreeObjOld"
                    :default-checked-keys="menuTreeObjApp"
                    :props="treeProps"
                />
            </el-tab-pane>
        </el-tabs>
        <template #footer>
            <el-button @click="visible = false">取 消</el-button>
            <el-button type="primary" @click="submit">确 定</el-button>
            <el-button color="#2B2B4C" @click="visible = false">取消</el-button>
            <el-button color="#284FE3" type="primary" @click="submit">确定</el-button>
        </template>
    </el-dialog>
</template>
@@ -88,23 +62,14 @@
    label: 'title',
    value: 'key',
}
const menuGrantList = ref([])
const menuGrantListApp = ref([])
const menuGrantListOld = ref([])
const menuGrantListNew = ref([])
const menuGrantListDroneControl = ref([])
const menuGrantListWord = ref([])
const menuTreeObj = ref([])
const menuTreeObjApp = ref([])
const menuTreeObjOld = ref([])
const menuTreeObjNew = ref([])
const droneControlMenuTreeObj = ref([])
const menuTreeObjWork = ref([])
const treeMenu = ref(null)
const treeMenuApp = ref(null)
const treeMenuWebOld = ref(null)
const treeMenuWebNew = ref(null)
const workRef = ref(null)
const droneControl = ref(null)
@@ -112,16 +77,10 @@
const route = useRoute()
function resetState() {
    menuGrantList.value = []
    menuGrantListApp.value = []
    menuGrantListOld.value = []
    menuGrantListNew.value = []
    menuGrantListDroneControl.value = []
    menuGrantListWord.value = []
    menuTreeObj.value = []
    menuTreeObjApp.value = []
    menuTreeObjOld.value = []
    menuTreeObjNew.value = []
    droneControlMenuTreeObj.value = []
    menuTreeObjWork.value = []
}
@@ -138,25 +97,19 @@
    visible.value = true
    resetState()
    await Promise.all([
        loadGrantTree(1, menuGrantList, menuTreeObj),
        loadGrantTree(3, menuGrantListApp, menuTreeObjApp),
        loadGrantTree(4, menuGrantListNew, menuTreeObjNew),
        loadGrantTree(5, menuGrantListDroneControl, droneControlMenuTreeObj),
        loadGrantTree(6, menuGrantListWord, menuTreeObjWork),
        loadGrantTree(2, menuGrantListOld, menuTreeObjOld),
    ])
}
function submit() {
    const menuList = treeMenu.value?.getCheckedKeys?.() ?? []
    const menuListApp = treeMenuApp.value?.getCheckedKeys?.() ?? []
    const menuListWebNew = treeMenuWebNew.value?.getCheckedKeys?.() ?? []
    const menuListWebWork = workRef.value?.getCheckedKeys?.() ?? []
    const menuListDroneControl = droneControl.value?.getCheckedKeys?.() ?? []
    const menuListWebOld = treeMenuWebOld.value?.getCheckedKeys?.() ?? []
    grant(
        [roleId.value],
        [...menuList, ...menuListApp, ...menuListWebNew, ...menuListDroneControl, ...menuListWebOld, ...menuListWebWork],
        [...menuListApp, ...menuListDroneControl, ...menuListWebWork],
        [],
        []
    ).then(() => {
applications/task-work-order/src/page/index/top/index.vue
@@ -3,12 +3,12 @@
    <div class="top-bar__left">
      任务工单管理子系统
    </div>
    <div class="top-bar__right">
      <div class="top-user">
        <div class="icon-box">
         <img class="gateway" @click="jumpMH" src="@/assets/images/mh.png" alt="进入门户" title="进入门户">
        </div>
<!--        <div class="icon-box">-->
<!--         <img class="gateway" @click="jumpMH" src="@/assets/images/mh.png" alt="进入门户" title="进入门户">-->
<!--        </div>-->
        <el-dropdown>
          <span class="el-dropdown-link">
@@ -23,7 +23,7 @@
              <!-- <el-dropdown-item>
                <router-link to="/info/index">{{ $t('navbar.userinfo') }}</router-link>
              </el-dropdown-item> -->
              <el-dropdown-item @click="logout" divided>{{ $t('navbar.logOut') }}
              <el-dropdown-item @click="logout">{{ $t('navbar.logOut') }}
              </el-dropdown-item>
            </el-dropdown-menu>
          </template>
applications/task-work-order/src/views/orderView/organizational/agenciesManagement/FormDiaLog.vue
@@ -43,15 +43,22 @@
        </el-col>
        <el-col :span="12">
          <el-form-item label="所属区划" prop="areaCode">
            <el-select
            <el-tree-select
              class="gd-select"
              popper-class="gd-select-popper"
              popper-class="gd-tree-select-popper"
              v-model="formData.areaCode"
              :data="regionOptions"
              node-key="id"
              :props="{
                value: 'id',
                label: 'name',
                children: 'children'
              }"
              placeholder="请选择"
              clearable
            >
              <el-option v-for="item in regionOptions" :key="item.value" :label="item.title" :value="item.value" />
            </el-select>
              filterable
              :check-strictly="true"
            />
          </el-form-item>
        </el-col>
        <el-col :span="12">
applications/task-work-order/src/views/orderView/organizational/agenciesManagement/index.vue
@@ -22,16 +22,19 @@
      </el-form-item>
      <el-form-item label="所属区划" prop="areaCode">
        <el-select
        <el-tree-select
          class="gd-select gray"
          popper-class="gd-select-popper"
          popper-class="gd-tree-select-popper"
          v-model="searchParams.areaCode"
          :data="regionOptions"
          node-key="id"
          :props="treeSelectProps"
          placeholder="请选择"
          clearable
          filterable
          @change="handleSearch"
        >
          <el-option v-for="item in regionOptions" :key="item.value" :label="item.title" :value="item.value" />
        </el-select>
          :check-strictly="true"
        />
      </el-form-item>
      <el-form-item class="gd-search-actions">
@@ -100,7 +103,6 @@
      @close="handleImportClose"
    >
      <el-form class="gd-dialog-form" ref="importFormRef" :model="importParams" :rules="importRules" label-width="140px">
        <el-form-item label="上传文件" prop="file">
          {{ importFileName }}
          <el-upload class="avatar-uploader" action="" :show-file-list="false" :before-upload="onImportFileBefore">
@@ -158,6 +160,14 @@
const regionOptions = ref([]) // 区域选项
const dictObj = ref({}) // 字典对象
// 树形选择器配置
const treeSelectProps = {
  value: 'id',
  label: 'name',
  children: 'children'
}
// 导入机构相关
const isShowImportView = ref(false)
const importFileName = ref('')
@@ -181,13 +191,38 @@
  })
}
// 获取区域列表
function getRegionList() {
  regionLazyTreeApi({parentCode: '360800000000'}).then(res => {
  console.log('区域列表', res.data.data);
    regionOptions.value = res.data.data || []
  })
// 递归获取区域树形数据
async function getRegionTree(parentCode = '360800000000') {
  try {
    const res = await regionLazyTreeApi({ parentCode })
    const nodes = res?.data?.data || []
    // 如果节点有子节点,递归获取子节点
    for (let node of nodes) {
      if (node.hasChildren) {
        node.children = await getRegionTree(node.id)
      } else {
        node.children = []
      }
      node.name = node.name || node.title || node.label
      // 确保 id 属性存在
      node.id = node.id || node.value
    }
    return nodes
  } catch (error) {
    console.error('获取区域数据失败:', error)
    return []
  }
}
// 获取完整的区域树形数据
async function getRegionList() {
  try {
    regionOptions.value = await getRegionTree()
    console.log('区域树形数据:', regionOptions.value)
  } catch (error) {
    ElMessage.error('获取区域数据失败')
  }
}
// 获取列表
@@ -274,7 +309,13 @@
// 上传文件前处理
function onImportFileBefore(file) {
  // 执行文件上传
  // 检查文件类型
  const allowedTypes = ['.xlsx', '.xls']
  const fileExtension = file.name.substring(file.name.lastIndexOf('.')).toLowerCase()
  if (!allowedTypes.includes(fileExtension)) {
    ElMessage.error('请上传Excel文件(.xlsx 或 .xls)')
    return false
  }
  let data = new FormData()
  data.append('file', file)
@@ -301,8 +342,12 @@
    if (valid) {
      importSubmitting.value = true
      try {
        // 这里实际上传文件的逻辑已经在onImportFileBefore中处理了
        // 这里可以添加额外的验证或逻辑
        if (!importParams.value.file) {
          ElMessage.error('请先上传文件')
          return
        }
        // 触发上传操作
        await onImportFileBefore(importParams.value.file)
      } finally {
        importSubmitting.value = false
      }