吉安感知网项目-前端
罗广辉
2026-02-27 3cf3cd88a7b7a49e3300e8e8c1e9034eb69a3429
Merge remote-tracking branch 'origin/master'
29 files modified
1 files added
638 ■■■■ changed files
applications/drone-command/src/api/system/user.js 3 ●●●● patch | view | raw | blame | history
applications/drone-command/src/views/permissionManage/permissionUser/index.vue 4 ●●●● patch | view | raw | blame | history
applications/mobile-web-view/src/appPages/voiceCallDetail/index.vue 7 ●●●● patch | view | raw | blame | history
applications/mobile-web-view/src/axios.js 10 ●●●● patch | view | raw | blame | history
applications/mobile-web-view/vite.config.mjs 15 ●●●● patch | view | raw | blame | history
applications/task-work-order/src/api/system/user.js 3 ●●●● patch | view | raw | blame | history
applications/task-work-order/src/styles/common/cockpit.scss 6 ●●●● patch | view | raw | blame | history
applications/task-work-order/src/views/basicManage/maintainRecord/index.vue 56 ●●●● patch | view | raw | blame | history
applications/task-work-order/src/views/orderView/appConfiguration/inventory/index.vue 2 ●●● patch | view | raw | blame | history
applications/task-work-order/src/views/orderView/appConfiguration/materials/index.vue 2 ●●● patch | view | raw | blame | history
applications/task-work-order/src/views/orderView/appConfiguration/process/index.vue 2 ●●● patch | view | raw | blame | history
applications/task-work-order/src/views/orderView/deviceInvocation/deviceCallRecord/FormDiaLog.vue 56 ●●●● patch | view | raw | blame | history
applications/task-work-order/src/views/orderView/deviceInvocation/deviceCallRecord/deviceCallRecordApi.js 19 ●●●●● patch | view | raw | blame | history
applications/task-work-order/src/views/orderView/deviceInvocation/deviceCallRecord/index.vue 176 ●●●● patch | view | raw | blame | history
applications/task-work-order/src/views/orderView/flyingHand/index.vue 2 ●●● patch | view | raw | blame | history
applications/task-work-order/src/views/orderView/orderDataManage/appInnovation/index.vue 2 ●●● patch | view | raw | blame | history
applications/task-work-order/src/views/orderView/orderDataManage/dataObjection/index.vue 2 ●●● patch | view | raw | blame | history
applications/task-work-order/src/views/orderView/orderDataManage/evaluate/index.vue 2 ●●● patch | view | raw | blame | history
applications/task-work-order/src/views/orderView/orderDataManage/supplyAdd/index.vue 2 ●●● patch | view | raw | blame | history
applications/task-work-order/src/views/orderView/orderManage/inspectionReport/index.vue 2 ●●● patch | view | raw | blame | history
applications/task-work-order/src/views/orderView/orderManage/inspectionRequest/index.vue 84 ●●●● patch | view | raw | blame | history
applications/task-work-order/src/views/orderView/orderManage/operatingIncome/index.vue 7 ●●●●● patch | view | raw | blame | history
applications/task-work-order/src/views/orderView/orderManage/orderManage/index.vue 75 ●●●● patch | view | raw | blame | history
applications/task-work-order/src/views/orderView/organizational/agenciesManagement/index.vue 2 ●●● patch | view | raw | blame | history
applications/task-work-order/src/views/orderView/organizational/roleMange/index.vue 2 ●●● patch | view | raw | blame | history
applications/task-work-order/src/views/orderView/organizational/userMange/index.vue 4 ●●●● patch | view | raw | blame | history
applications/task-work-order/src/views/orderView/organizational/zoningManagement/index.vue 2 ●●● patch | view | raw | blame | history
uniapps/work-app/src/hooks/useGlobalWS.js 61 ●●●●● patch | view | raw | blame | history
uniapps/work-app/src/subPackages/voiceCallDetail/index.vue 6 ●●●● patch | view | raw | blame | history
uniapps/work-app/src/utils/websocket.js 22 ●●●● patch | view | raw | blame | history
applications/drone-command/src/api/system/user.js
@@ -1,6 +1,6 @@
import request from '@/axios';
export const getList = (current, size,params, deptId) => {
export const getList = (current, size,sysType,params, deptId) => {
  return request({
    url: '/blade-system/user/page',
    method: 'get',
@@ -8,6 +8,7 @@
      ...params,
      current,
      size,
      sysType,
      deptId,
    },
  });
applications/drone-command/src/views/permissionManage/permissionUser/index.vue
@@ -110,7 +110,7 @@
    deptId: '',
    current: 1,
    size: 10,
    // sysType: 5,
    sysType: 5,
})
const searchParams = ref(initSearchParams())
@@ -135,7 +135,7 @@
        const res = await getUserList(
            searchParams.value.current,
            searchParams.value.size,
            // searchParams.value.sysType,
            searchParams.value.sysType,
            {
                account: searchParams.value.account,
                realName: searchParams.value.realName,
applications/mobile-web-view/src/appPages/voiceCallDetail/index.vue
@@ -466,7 +466,8 @@
    // 你后端没有 reject,用 busy 表示拒绝/不可接听
    send('busy', incomingFrom, null)
    log('❌ 已拒绝来电,发送 busy 给', incomingFrom)
    const transmitData = { data: { type: 'hangupVoice' } }
uni.postMessage(transmitData)
    // 停止铃声
//     const transmitData = { data: { type: 'stopVoice' } }
// uni.postMessage(transmitData)
@@ -572,6 +573,8 @@
        } else {
            log('❌ uni对象不存在,无法返回上一页')
        }
        const transmitData = { data: { type: 'hangupVoice' } }
        uni.postMessage(transmitData)
    } else {
        // 对方挂断:显示提示,延迟10秒跳转
        callEnded.value = true
@@ -585,6 +588,8 @@
            } else {
                log('❌ uni对象不存在,无法返回上一页')
            }
            const transmitData = { data: { type: 'hangupVoice' } }
            uni.postMessage(transmitData)
            // 重置通话结束状态
            callEnded.value = false
        }, 3000)
applications/mobile-web-view/src/axios.js
@@ -40,11 +40,11 @@
    config => {
        // 初始化错误提示状态
        isErrorShown = false
        if (VITE_APP_ENV === 'development') {
            config.url = VITE_APP_API + config.url
        } else {
            config.url = VITE_APP_XT_URL + config.url
        }
        // if (VITE_APP_ENV === 'development') {
        //     config.url = VITE_APP_API + config.url
        // } else {
        //     config.url = VITE_APP_XT_URL + config.url
        // }
        config.headers['areaCode'] = store.state.user.selectedAreaCode
        //安全请求header
        config.headers['Blade-Requested-With'] = 'BladeHttpRequest'
applications/mobile-web-view/vite.config.mjs
@@ -6,7 +6,7 @@
import createVitePlugins from './vite/plugins'
import postCssPxToRem from 'postcss-pxtorem'
import { fileURLToPath, URL } from "node:url"
import  basic from '@vitejs/plugin-basic-ssl'
import fs from 'fs'
// https://vitejs.dev/config/
@@ -19,6 +19,7 @@
  const {
    VITE_APP_ENV,
    VITE_APP_BASE,
    VITE_APP_API_URL,
        VITE_APP_XT_URL,
    VITE_APP_RECTANGLE,
    VITE_APP_ARCGIS_URL,
@@ -67,6 +68,7 @@
      //   key: fs.readFileSync('./127.0.0.1+3-key.pem'), // 私钥路径
      //   cert: fs.readFileSync('./127.0.0.1+3.pem'), // 证书路径
      // },
      https: true,
      port: 5179,
      proxy: {
        '/aisky-webodm-vol': {
@@ -111,8 +113,14 @@
          rewrite: path => path.replace(/^\/dji_in_rectangle/, ''),
        },
        '/api': {
        '/webservice': {
          target: VITE_APP_XT_URL,
          changeOrigin: true,
          rewrite: path => path.replace(/^\/webservice/, '/webservice'),
        },
        '/api': {
          target: VITE_APP_API_URL,
          changeOrigin: true,
          rewrite: path => path.replace(/^\/api/, ''),
        }
@@ -149,7 +157,8 @@
        ]
      }
    },
    plugins: createVitePlugins(env, command === 'build'),
    plugins: [...createVitePlugins(env, command === 'build'), basic()],
    // plugins: createVitePlugins(env, command === 'build'),
    build: buildConfig,
    optimizeDeps: {
      esbuildOptions: {
applications/task-work-order/src/api/system/user.js
@@ -1,6 +1,6 @@
import request from '@/axios';
export const getList = (current, size, params, deptId) => {
export const getList = (current, size,sysType, params, deptId) => {
  return request({
    url: '/blade-system/user/page',
    method: 'get',
@@ -8,6 +8,7 @@
      ...params,
      current,
      size,
      sysType,
      deptId,
    },
  });
applications/task-work-order/src/styles/common/cockpit.scss
@@ -721,7 +721,7 @@
}
.gd-pagination-parent {
  padding-top: 30px;
  margin: 16px 0;
  display: flex;
  justify-content: flex-end;
@@ -845,7 +845,7 @@
}
.gd-search-form {
  padding-bottom: 20px;
  padding-bottom: 15px;
  display: flex;
  .el-form-item__label {
@@ -924,7 +924,7 @@
}
.gd-table-container {
  padding: 12px 20px 30px 20px;
  padding: 25px 20px 1px;
  height: 0;
  flex: 1;
  display: flex;
applications/task-work-order/src/views/basicManage/maintainRecord/index.vue
@@ -2,45 +2,21 @@
    <basic-container>
        <el-form ref="queryParamsRef" :model="searchParams" class="gd-search-form">
            <el-form-item label="设备名称" prop="deviceName">
                <el-input
                    class="gd-input"
                    v-model="searchParams.deviceName"
                    placeholder="请输入"
                    clearable
                    @clear="handleSearch"
                />
                <el-input class="gd-input" v-model="searchParams.deviceName" placeholder="请输入" clearable
                    @clear="handleSearch" />
            </el-form-item>
            <el-form-item label="设备类型" prop="deviceType">
                <el-select
                    class="gd-select"
                    popper-class="gd-select-popper"
                    v-model="searchParams.deviceType"
                    placeholder="请选择"
                    clearable
                    @change="handleSearch"
                >
                    <el-option
                        v-for="item in dictObj.deviceType"
                        :key="item.dictKey"
                        :label="item.dictValue"
                        :value="item.dictKey"
                    />
                <el-select class="gd-select" popper-class="gd-select-popper" v-model="searchParams.deviceType"
                    placeholder="请选择" clearable @change="handleSearch">
                    <el-option v-for="item in dictObj.deviceType" :key="item.dictKey" :label="item.dictValue"
                        :value="item.dictKey" />
                </el-select>
            </el-form-item>
            <el-form-item label="所属部门" prop="belongDept">
                <el-tree-select
                    class="gd-select"
                    popper-class="gd-tree-select-popper"
                    v-model="searchParams.belongDept"
                    :data="deptTree"
                    :props="treeProps"
                    node-key="id"
                    check-strictly
                    clearable
                    @change="handleSearch"
                />
                <el-tree-select class="gd-select" popper-class="gd-tree-select-popper" v-model="searchParams.belongDept"
                    :data="deptTree" :props="treeProps" node-key="id" check-strictly clearable @change="handleSearch" />
            </el-form-item>
            <el-form-item class="gd-search-actions">
@@ -49,12 +25,13 @@
            </el-form-item>
        </el-form>
        <div class="gd-table-container" v-loading="loading">
        <div class="gd-table-toolbar">
            <el-button :icon="Plus" color="#4C34FF" type="primary" @click="openForm('add')">新增</el-button>
            <el-button :icon="Delete" color="#4C34FF" :disabled="!selectedIds.length" @click="handleDelete()">删除</el-button>
                <el-button :icon="Delete" color="#4C34FF" :disabled="!selectedIds.length"
                    @click="handleDelete()">删除</el-button>
        </div>
        <div class="gd-table-container" v-loading="loading">
            <div class="gd-table-content gd-table-content-bg">
                <el-table class="gd-table" :data="list" @selection-change="handleSelectionChange">
                    <el-table-column type="selection" width="46" />
@@ -85,14 +62,9 @@
            </div>
            <div class="gd-pagination-parent">
                <el-pagination
                    popper-class="gd-select-popper"
                    v-model:current-page="searchParams.current"
                    v-model:page-size="searchParams.size"
                    layout="total, prev, pager, next, sizes"
                    :total="total"
                    @change="getList"
                />
                <el-pagination popper-class="gd-select-popper" v-model:current-page="searchParams.current"
                    v-model:page-size="searchParams.size" layout="total, prev, pager, next, sizes" :total="total"
                    @change="getList" />
            </div>
        </div>
applications/task-work-order/src/views/orderView/appConfiguration/inventory/index.vue
@@ -45,11 +45,11 @@
            </el-form-item>
        </el-form>
        <div class="gd-table-container" v-loading="loading">
        <div class="gd-table-toolbar">
            <el-button :icon="Plus" color="#4C34FF" type="primary" @click="openForm('add')">新增</el-button>
        </div>
        <div class="gd-table-container" v-loading="loading">
            <div class="gd-table-content gd-table-content-bg">
                <el-table class="gd-table" :data="list">
                    <el-table-column label="序号" width="80">
applications/task-work-order/src/views/orderView/appConfiguration/materials/index.vue
@@ -17,11 +17,11 @@
            </el-form-item>
        </el-form>
        <div class="gd-table-container" v-loading="loading">
        <div class="gd-table-toolbar">
            <el-button :icon="Plus" color="#4C34FF" type="primary" @click="openForm('add')">新增材料</el-button>
        </div>
        <div class="gd-table-container" v-loading="loading">
            <div class="gd-table-content gd-table-content-bg">
                <el-table class="gd-table" :data="list">
                    <el-table-column label="序号" width="80">
applications/task-work-order/src/views/orderView/appConfiguration/process/index.vue
@@ -27,6 +27,7 @@
            </el-form-item>
        </el-form>
        <div class="gd-table-container" v-loading="loading">
        <div class="gd-table-toolbar">
            <el-button :icon="Plus" color="#4C34FF" type="primary"  @click="handleCreate">
                创建
@@ -40,7 +41,6 @@
            </el-button>
        </div>
        <div class="gd-table-container" v-loading="loading">
            <div class="gd-table-content gd-table-content-bg">
                <el-table class="gd-table" :data="list" @selection-change="selectionChange">
                    <el-table-column type="selection" width="55" />
applications/task-work-order/src/views/orderView/deviceInvocation/deviceCallRecord/FormDiaLog.vue
@@ -2,10 +2,10 @@
    <el-dialog class="gd-dialog" v-model="visible" :title="dialogTitle" @closed="handleClosed" destroy-on-close
                         :close-on-click-modal="false">
        <!--        <div class="detail-row-view" v-if="dialogReadonly">-->
        <el-table :data="list" class="gd-dialog-table">
            <el-table-column prop="resultCode" show-overflow-tooltip label="序号" />
            <el-table-column prop="resultCode" show-overflow-tooltip label="设备状态" />
            <el-table-column prop="shootTime" show-overflow-tooltip label="发生时间" />
        <el-table :data="detailsList" class="gd-dialog-table">
            <el-table-column type="index" show-overflow-tooltip label="序号" />
            <el-table-column prop="deviceStatus" show-overflow-tooltip label="设备状态" />
            <el-table-column prop="occurTime" show-overflow-tooltip label="发生时间" />
        </el-table>
    </el-dialog>
</template>
@@ -13,28 +13,19 @@
<script setup>
import { computed, onMounted, ref } from 'vue'
import { ElMessage } from 'element-plus'
import { add, getUser, update } from '@/api/system/user'
import { getDeviceCallRecordDetails } from './deviceCallRecordApi'
import { getDeptTree } from '@/api/system/dept'
import { getRoleTree } from '@/api/system/role'
import func from '@/utils/func'
import { saveOperationLog } from '@ztzf/apis'
import { useRoute } from 'vue-router'
const list = ref([])
const detailsList = ref([])
const initForm = () => ({
    account: '',
    password: '',
    password2: '',
    realName: '',
    phone: '',
    email: '',
    sex: null,
    birthday: '',
    code: '',
    roleId: '',
    deptId: '',
    // sysType: 6
    callId: '',
    size: 10,
    current: 1
})
const treeProps = {
@@ -80,28 +71,16 @@
    }
}
async function getRoleTreeData() {
    const res = await getRoleTree('000000')
    roleTree.value = res.data.data
}
async function getDeptTreeData() {
    const res = await getDeptTree('000000')
    deptTree.value = res.data.data
}
function handleCancel() {
    visible.value = false
}
async function loadDetail() {
    if (!formData.value.id) return
    const res = await getUser(formData.value.id)
    const data = res?.data?.data ?? {}
    if (data.roleId) {
        data.roleId = func.split(data.roleId)[0] || data.roleId
    }
    formData.value = data
async function loadDetail(id) {
    formData.value.id = id
    const res = await getDeviceCallRecordDetails(formData)
    detailsList.value = res?.data?.data.records
}
function handleClosed() {
@@ -111,17 +90,10 @@
async function open({ mode, row } = {}) {
    dialogMode.value = mode || 'add'
    visible.value = true
    if (dialogMode.value === 'add') {
        formData.value = initForm()
        return
    }
    formData.value = { id: row.id }
    await loadDetail()
    await loadDetail(row.id)
}
onMounted(() => {
    getRoleTreeData()
    getDeptTreeData()
})
defineExpose({ open })
applications/task-work-order/src/views/orderView/deviceInvocation/deviceCallRecord/deviceCallRecordApi.js
New file
@@ -0,0 +1,19 @@
import request from '@/axios'
// 设备分页查询
export function getDeviceCallRecordPage(params) {
    return request({
        url: '/drone-gd/workorder/gdDeviceCall/page',
        method: 'get',
        params
    })
}
export function getDeviceCallRecordDetails(params) {
    return request({
        url: `/drone-gd/workorder/gdDeviceCallDetail/page`,
        method: 'get',
        params
    })
}
applications/task-work-order/src/views/orderView/deviceInvocation/deviceCallRecord/index.vue
@@ -1,38 +1,50 @@
<template>
    <basic-container>
        <el-form ref="queryParamsRef" :model="searchParams" class="gd-search-form">
            <el-form-item label="登录账号" prop="account">
            <el-form-item label="任务名称" prop="patrolTaskName">
                <el-input
                    class="gd-input gray"
                    v-model="searchParams.account"
                    v-model="searchParams.patrolTaskName"
                    placeholder="请输入"
                    clearable
                    @clear="handleSearch"
                />
            </el-form-item>
            <el-form-item label="用户姓名" prop="realName">
                <el-input
                    class="gd-input gray"
                    v-model="searchParams.realName"
                    placeholder="请输入"
                    clearable
                    @clear="handleSearch"
                />
            </el-form-item>
            <el-form-item label="所属部门" prop="deptId">
                <el-tree-select
            <el-form-item label="执行设备" prop="deviceId">
                <el-select
                    class="gd-select gray"
                    popper-class="gd-select-popper"
                    v-model="searchParams.deptId"
                    :data="deptTree"
                    :props="treeProps"
                    node-key="id"
                    check-strictly
                    v-model="searchParams.deviceId"
                    placeholder="请选择"
                    clearable
                    @change="handleSearch"
                >
                    <el-option
                        v-for="item in deviceList"
                        :key="item.id"
                        :label="item.nickname"
                        :value="item.id"
                />
                </el-select>
            </el-form-item>
            <el-form-item label="任务发起人" prop="">
                <el-select
                    class="gd-select gray"
                    popper-class="gd-select-popper"
                    v-model="searchParams.taskInitiator"
                    placeholder="请选择"
                    clearable
                    @change="handleSearch"
                >
                    <el-option
                        v-for="item in userList"
                        :key="item.id"
                        :label="item.realName"
                        :value="item.id"
                    />
                </el-select>
            </el-form-item>
            <el-form-item class="gd-search-actions">
@@ -41,33 +53,33 @@
            </el-form-item>
        </el-form>
        <div class="gd-table-toolbar">
            <el-button v-if="permission.orderUser_add" :icon="Plus" color="#4C34FF" type="primary" @click="handleAdd">
                新增
            </el-button>
            <el-button
                v-if="permission.orderUser_remove"
                :icon="Delete"
                :disabled="!selectedIds.length"
                @click="handleDelete()"
            >
                删除
            </el-button>
        </div>
<!--        <div class="gd-table-toolbar">-->
<!--            <el-button v-if="permission.orderUser_add" :icon="Plus" color="#4C34FF" type="primary" @click="handleAdd">-->
<!--                新增-->
<!--            </el-button>-->
<!--            <el-button-->
<!--                v-if="permission.orderUser_remove"-->
<!--                :icon="Delete"-->
<!--                :disabled="!selectedIds.length"-->
<!--                @click="handleDelete()"-->
<!--            >-->
<!--                删除-->
<!--            </el-button>-->
<!--        </div>-->
        <div class="gd-table-container" v-loading="loading">
            <div class="gd-table-content gd-table-content-bg">
                <el-table class="gd-table" :data="list" @selection-change="handleSelectionChange">
                <el-table class="gd-table" :data="list">
                    <el-table-column type="selection" width="46" />
                    <el-table-column type="index" show-overflow-tooltip width="64" label="序号" />
                    <el-table-column prop="account" show-overflow-tooltip label="任务名称" />
                    <el-table-column prop="realName" show-overflow-tooltip label="发起任务部门" />
                    <el-table-column prop="roleName" show-overflow-tooltip label="任务发起人" />
                    <el-table-column prop="deptName" show-overflow-tooltip label="飞行时长" />
                    <el-table-column prop="phone" show-overflow-tooltip label="飞行里程(m)" />
                    <el-table-column prop="phone" show-overflow-tooltip label="执行设备" />
                    <el-table-column prop="phone" show-overflow-tooltip label="计划执行时间" />
                    <el-table-column prop="phone" show-overflow-tooltip label="实际执行时间" />
                    <el-table-column prop="patrolTaskName" show-overflow-tooltip label="任务名称" />
                    <el-table-column prop="taskDepartment" show-overflow-tooltip label="发起任务部门" />
                    <el-table-column prop="taskInitiator" show-overflow-tooltip label="任务发起人" />
                    <el-table-column prop="flightDuration" show-overflow-tooltip label="飞行时长" />
                    <el-table-column prop="flightDistance" show-overflow-tooltip label="飞行里程(m)" />
                    <el-table-column prop="deviceName" show-overflow-tooltip label="执行设备" />
                    <el-table-column prop="planExecuteTime" show-overflow-tooltip label="计划执行时间" />
                    <el-table-column prop="actualExecuteTime" show-overflow-tooltip label="实际执行时间" />
                    <el-table-column label="操作" class-name="operation-btns" width="180">
                        <template v-slot="{ row }">
                            <el-link  @click="handleView(row)">查看</el-link>
@@ -97,19 +109,20 @@
import { computed, onMounted, ref } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { getDeptTree } from '@/api/system/dept'
import { getList as getUserList, remove } from '@/api/system/user'
import { getDeviceCallRecordPage } from './deviceCallRecordApi'
import { getEquipmentPage } from '../equipmentResource/equipmentResourceApi'
import { getList as getUserList } from '@/api/system/user'
import { useStore } from 'vuex'
import FormDiaLog from './FormDiaLog.vue'
import { saveOperationLog } from '@ztzf/apis'
import { useRoute } from 'vue-router'
const initSearchParams = () => ({
    account: '',
    realName: '',
    deptId: '',
    deviceId: '',
    patrolTaskName: '',
    taskInitiator: '',
    current: 1,
    size: 10,
    // sysType: 6
})
const searchParams = ref(initSearchParams())
@@ -131,21 +144,32 @@
async function getList() {
    loading.value = true
    try {
        const res = await getUserList(
            searchParams.value.current,
            searchParams.value.size,
            // searchParams.value.sysType,
            {
                account: searchParams.value.account,
                realName: searchParams.value.realName,
            },
            searchParams.value.deptId
        )
        const res = await getDeviceCallRecordPage(searchParams)
        list.value = res?.data?.data?.records ?? []
        total.value = res?.data?.data?.total ?? 0
    } finally {
        loading.value = false
    }
}
// 获取设备列表
const deviceList = ref([])
async function getDeviceList(row) {
    const params = {
        deviceType: 1, // 设备类型
        modeCode: '', // 设备状态
        current: 1, // 当前页
        size: 999, // 每页大小
    }
    const res = await getEquipmentPage(params)
    deviceList.value = res?.data?.data?.records ?? []
}
// 获取用户列表
const userList = ref([])
async function getUserListPage() {
    const res = await getUserList(1,999)
    userList.value = res?.data?.data?.records ?? []
}
function handleSearch() {
@@ -160,51 +184,15 @@
    getList()
}
function handleAdd() {
    dialogRef.value?.open({ mode: 'add' })
}
function handleView(row) {
    dialogRef.value?.open({ mode: 'view', row: { ...row } })
}
function handleEdit(row) {
    dialogRef.value?.open({ mode: 'edit', row: { ...row } })
}
async function handleDelete(row) {
    const tips = row ? '该条' : '选中的项'
    await ElMessageBox.confirm(`确认删除${tips}吗?`, '提示', {
        type: 'warning',
        customClass: 'command-page-view-message-box',
        confirmButtonClass: 'command-message-box-confirm',
        cancelButtonClass: 'command-message-box-cancel',
    })
    const ids = row ? row.id : selectedIds.value.join(',')
    await remove(ids)
    saveOperationLog({
        requestUri: route.path,
        title: `${route.name || '用户管理'}-删除`,
        type: 1
    })
    ElMessage.success('删除成功')
    selectedIds.value = []
    getList()
}
function handleSelectionChange(rows) {
    selectedIds.value = rows.map(item => item.id)
}
function getDeptTreeList() {
    getDeptTree().then(res => {
        deptTree.value = res?.data?.data ?? []
    })
}
onMounted(() => {
    getDeviceList()
    getUserListPage()
    getList()
    getDeptTreeList()
})
</script>
applications/task-work-order/src/views/orderView/flyingHand/index.vue
@@ -48,11 +48,11 @@
            </el-form-item>
        </el-form>
        <div class="gd-table-container" v-loading="loading">
        <div class="gd-table-toolbar">
            <el-button :icon="Plus" color="#4C34FF" type="primary" @click="addFlyingHand">飞手建档</el-button>
        </div>
        <div class="gd-table-container" v-loading="loading">
            <div class="gd-table-content gd-table-content-bg">
                <el-table class="gd-table" :data="list">
                    <el-table-column type="index" width="64" label="序号" />
applications/task-work-order/src/views/orderView/orderDataManage/appInnovation/index.vue
@@ -35,12 +35,12 @@
            </el-form-item>
        </el-form>
        <div class="gd-table-container" v-loading="loading">
        <div class="gd-table-toolbar">
            <el-button :icon="Plus" color="#4C34FF" type="primary" @click="openForm('add')">应用创新新增</el-button>
            <!-- <el-button :icon="Delete" color="#4C34FF" :disabled="!selectedIds.length" @click="handleDelete()">删除</el-button> -->
        </div>
        <div class="gd-table-container" v-loading="loading">
            <div class="gd-table-content gd-table-content-bg">
                <el-table class="gd-table" :data="list" @selection-change="handleSelectionChange">
                    <el-table-column label="序号" width="70" align="center">
applications/task-work-order/src/views/orderView/orderDataManage/dataObjection/index.vue
@@ -35,12 +35,12 @@
            </el-form-item>
        </el-form>
        <div class="gd-table-container" v-loading="loading">
        <div class="gd-table-toolbar">
            <el-button :icon="Plus" color="#4C34FF" type="primary" @click="openForm('add')">数据异议申请</el-button>
            <!--            -->
        </div>
        <div class="gd-table-container" v-loading="loading">
            <div class="gd-table-content gd-table-content-bg">
                <el-table class="gd-table" :data="list">
                    <el-table-column label="序号" width="70">
applications/task-work-order/src/views/orderView/orderDataManage/evaluate/index.vue
@@ -31,11 +31,11 @@
            </el-form-item>
        </el-form>
        <div class="gd-table-container" v-loading="loading">
        <div class="gd-table-toolbar">
            <el-button :icon="Plus" color="#4C34FF" type="primary" @click="openForm('add')">新增评价</el-button>
        </div>
        <div class="gd-table-container" v-loading="loading">
            <div class="gd-table-content gd-table-content-bg">
                <el-table class="gd-table" :data="list">
                    <el-table-column label="序号" width="80">
applications/task-work-order/src/views/orderView/orderDataManage/supplyAdd/index.vue
@@ -35,11 +35,11 @@
            </el-form-item>
        </el-form>
        <div class="gd-table-container" v-loading="loading">
        <div class="gd-table-toolbar" v-if="permissionList.addBtn">
            <el-button :icon="Plus" color="#4C34FF" type="primary" @click="openForm('add')">供需填报新增</el-button>
        </div>
        <div class="gd-table-container" v-loading="loading">
            <div class="gd-table-content gd-table-content-bg">
                <el-table class="gd-table" :data="list">
                    <el-table-column label="序号" width="70" align="center">
applications/task-work-order/src/views/orderView/orderManage/inspectionReport/index.vue
@@ -36,12 +36,12 @@
            </el-form-item>
        </el-form>
        <div class="gd-table-container" v-loading="loading">
        <div class="gd-table-toolbar">
            <el-button :icon="Download" color="#4C34FF" type="primary" @click="handleDownload">文档下载</el-button>
            <el-button :icon="Upload" color="#4C34FF" type="primary" @click="handleUpload">文档上传</el-button>
        </div>
        <div class="gd-table-container" v-loading="loading">
            <div class="gd-table-content gd-table-content-bg">
                <el-table class="gd-table" :data="list" @selection-change="handleSelectionChange">
                    <el-table-column type="selection" width="46" />
applications/task-work-order/src/views/orderView/orderManage/inspectionRequest/index.vue
@@ -6,63 +6,30 @@
        </el-tabs>
        <el-form ref="queryParamsRef" :model="searchParams" class="gd-search-form">
            <el-form-item label="任务名称" prop="patrolTaskName">
                <el-input
                    class="gd-input gray"
                    v-model="searchParams.patrolTaskName"
                    placeholder="请输入"
                    clearable
                    @clear="handleSearch"
                />
                <el-input class="gd-input gray" v-model="searchParams.patrolTaskName" placeholder="请输入" clearable
                    @clear="handleSearch" />
            </el-form-item>
            <el-form-item label="任务类型" prop="patrolTaskType">
                <el-select
                    class="gd-select gray"
                    popper-class="gd-select-popper"
                    v-model="searchParams.patrolTaskType"
                    placeholder="请选择"
                    clearable
                    @change="handleSearch"
                >
                    <el-option
                        v-for="item in dictObj.workOrderType"
                        :key="item.dictKey"
                        :label="item.dictValue"
                        :value="item.dictKey"
                    />
                <el-select class="gd-select gray" popper-class="gd-select-popper" v-model="searchParams.patrolTaskType"
                    placeholder="请选择" clearable @change="handleSearch">
                    <el-option v-for="item in dictObj.workOrderType" :key="item.dictKey" :label="item.dictValue"
                        :value="item.dictKey" />
                </el-select>
            </el-form-item>
            <el-form-item label="任务状态" prop="taskStatus">
                <el-select
                    class="gd-select gray"
                    popper-class="gd-select-popper"
                    v-model="searchParams.taskStatus"
                    placeholder="请选择"
                    clearable
                    @change="handleSearch"
                >
                    <el-option
                        v-for="item in dictObj.taskStatus"
                        :key="item.dictKey"
                        :label="item.dictValue"
                        :value="item.dictKey"
                    />
                <el-select class="gd-select gray" popper-class="gd-select-popper" v-model="searchParams.taskStatus"
                    placeholder="请选择" clearable @change="handleSearch">
                    <el-option v-for="item in dictObj.taskStatus" :key="item.dictKey" :label="item.dictValue"
                        :value="item.dictKey" />
                </el-select>
            </el-form-item>
            <el-form-item label="执行时间" prop="executeTime">
                <el-date-picker
                    class="gd-date-picker gray"
                    popper-class="gd-date-picker-popper"
                    v-model="dateRange"
                    type="daterange"
                    range-separator="-"
                    start-placeholder="开始日期"
                    end-placeholder="结束日期"
                    value-format="YYYY-MM-DD HH:mm:ss"
                    @change="handleSearch"
                />
                <el-date-picker class="gd-date-picker gray" popper-class="gd-date-picker-popper" v-model="dateRange"
                    type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"
                    value-format="YYYY-MM-DD HH:mm:ss" @change="handleSearch" />
            </el-form-item>
            <el-form-item class="gd-search-actions">
@@ -71,13 +38,14 @@
            </el-form-item>
        </el-form>
        <div class="gd-table-container" v-loading="loading">
        <div class="gd-table-toolbar">
            <el-button v-if="permission.flyOrder_add" :icon="Plus" color="#4C34FF" type="primary" @click="openForm('add')">
                <el-button v-if="permission.flyOrder_add" :icon="Plus" color="#4C34FF" type="primary"
                    @click="openForm('add')">
                拆分工单
            </el-button>
        </div>
        <div class="gd-table-container" v-loading="loading">
            <div class="gd-table-content gd-table-content-bg">
                <el-table class="gd-table" :data="list" @selection-change="handleSelectionChange">
                    <!--                    <el-table-column type="selection" width="46" />-->
@@ -109,25 +77,15 @@
            </div>
            <div class="gd-pagination-parent">
                <el-pagination
                    popper-class="gd-select-popper"
                    v-model:current-page="searchParams.current"
                    v-model:page-size="searchParams.size"
                    layout="total, prev, pager, next, sizes"
                    :total="total"
                    @change="getList"
                />
                <el-pagination popper-class="gd-select-popper" v-model:current-page="searchParams.current"
                    v-model:page-size="searchParams.size" layout="total, prev, pager, next, sizes" :total="total"
                    @change="getList" />
            </div>
        </div>
        <FormDiaLog ref="dialogRef" @success="getList" v-if="dialogVisible" v-model="dialogVisible" />
        <ViewDiaLog
            ref="viewDiaLogRef"
            @success="getList"
            @refusalAccept="refusalAccept"
            v-if="viewDiaLogVisible"
            v-model="viewDiaLogVisible"
        />
        <ViewDiaLog ref="viewDiaLogRef" @success="getList" @refusalAccept="refusalAccept" v-if="viewDiaLogVisible"
            v-model="viewDiaLogVisible" />
    </basic-container>
</template>
<script setup>
applications/task-work-order/src/views/orderView/orderManage/operatingIncome/index.vue
@@ -1,11 +1,12 @@
<!-- 运营收益 -->
<template>
  <basic-container>
    <div class="gd-table-container" v-loading="loading">
    <div class="gd-table-toolbar">
      <el-button :icon="Plus" color="#4C34FF" type="primary" @click="handleAdd">新增</el-button>
      <el-button :icon="Delete" color="#4C34FF" :disabled="!selectedIds.length" @click="handleDelete()">删除</el-button>
    </div>
    <div class="gd-table-container" v-loading="loading">
      <div class="gd-table-content gd-table-content-bg">
        <el-table class="gd-table" :data="tableList" @selection-change="handleSelectionChange">
          <el-table-column type="selection" width="46" />
@@ -32,8 +33,8 @@
          v-model:page-size="params.size" layout="total, prev, pager, next, sizes" :total="total" @change="getList" />
      </div>
    </div>
    <el-dialog class="gd-dialog" append-to-body v-model="isShowEditView" :title="titleTxt"
      :close-on-click-modal="false" :destroy-on-close="true" @close="handleClose">
    <el-dialog class="gd-dialog" append-to-body v-model="isShowEditView" :title="titleTxt" :close-on-click-modal="false"
      :destroy-on-close="true" @close="handleClose">
      <el-form class="gd-dialog-form" ref="ruleFormRef" :model="editParams" :rules="rules" label-width="160px">
        <el-row>
                <el-col :span="12">
applications/task-work-order/src/views/orderView/orderManage/orderManage/index.vue
@@ -6,63 +6,30 @@
        </el-tabs>
        <el-form ref="queryParamsRef" :model="searchParams" class="gd-search-form">
            <el-form-item label="工单名称" prop="workOrderName">
                <el-input
                    class="gd-input gray"
                    v-model="searchParams.workOrderName"
                    placeholder="请输入"
                    clearable
                    @clear="handleSearch"
                />
                <el-input class="gd-input gray" v-model="searchParams.workOrderName" placeholder="请输入" clearable
                    @clear="handleSearch" />
            </el-form-item>
            <el-form-item label="工单类型" prop="workOrderType">
                <el-select
                    class="gd-select gray"
                    popper-class="gd-select-popper"
                    v-model="searchParams.workOrderType"
                    placeholder="请选择"
                    clearable
                    @change="handleSearch"
                >
                    <el-option
                        v-for="item in dictObj.workOrderType"
                        :key="item.dictKey"
                        :label="item.dictValue"
                        :value="item.dictKey"
                    />
                <el-select class="gd-select gray" popper-class="gd-select-popper" v-model="searchParams.workOrderType"
                    placeholder="请选择" clearable @change="handleSearch">
                    <el-option v-for="item in dictObj.workOrderType" :key="item.dictKey" :label="item.dictValue"
                        :value="item.dictKey" />
                </el-select>
            </el-form-item>
            <el-form-item label="工单状态" prop="workOrderStatus">
                <el-select
                    class="gd-select gray"
                    popper-class="gd-select-popper"
                    v-model="searchParams.workOrderStatus"
                    placeholder="请选择"
                    clearable
                    @change="handleSearch"
                >
                    <el-option
                        v-for="item in dictObj.workOrderStatus"
                        :key="item.dictKey"
                        :label="item.dictValue.split('_')[1]"
                        :value="item.dictKey"
                    />
                <el-select class="gd-select gray" popper-class="gd-select-popper" v-model="searchParams.workOrderStatus"
                    placeholder="请选择" clearable @change="handleSearch">
                    <el-option v-for="item in dictObj.workOrderStatus" :key="item.dictKey"
                        :label="item.dictValue.split('_')[1]" :value="item.dictKey" />
                </el-select>
            </el-form-item>
            <el-form-item label="执行时间" prop="executeTime">
                <el-date-picker
                    class="gd-date-picker gray"
                    popper-class="gd-date-picker-popper"
                    v-model="dateRange"
                    type="daterange"
                    range-separator="-"
                    start-placeholder="开始日期"
                    end-placeholder="结束日期"
                    value-format="YYYY-MM-DD HH:mm:ss"
                    @change="handleSearch"
                />
                <el-date-picker class="gd-date-picker gray" popper-class="gd-date-picker-popper" v-model="dateRange"
                    type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"
                    value-format="YYYY-MM-DD HH:mm:ss" @change="handleSearch" />
            </el-form-item>
            <el-form-item class="gd-search-actions">
@@ -71,13 +38,14 @@
            </el-form-item>
        </el-form>
        <div class="gd-table-container" v-loading="loading">
        <div class="gd-table-toolbar">
            <el-button v-if="permission.order_release" :icon="Plus" color="#4C34FF" type="primary" @click="openForm('add')">
                <el-button v-if="permission.order_release" :icon="Plus" color="#4C34FF" type="primary"
                    @click="openForm('add')">
                新增工单
            </el-button>
        </div>
        <div class="gd-table-container" v-loading="loading">
            <div class="gd-table-content gd-table-content-bg">
                <el-table class="gd-table" :data="list" @selection-change="handleSelectionChange">
                    <el-table-column type="index" width="64" label="序号" />
@@ -118,14 +86,9 @@
            </div>
            <div class="gd-pagination-parent">
                <el-pagination
                    popper-class="gd-select-popper"
                    v-model:current-page="searchParams.current"
                    v-model:page-size="searchParams.size"
                    layout="total, prev, pager, next, sizes"
                    :total="total"
                    @change="getList"
                />
                <el-pagination popper-class="gd-select-popper" v-model:current-page="searchParams.current"
                    v-model:page-size="searchParams.size" layout="total, prev, pager, next, sizes" :total="total"
                    @change="getList" />
            </div>
        </div>
applications/task-work-order/src/views/orderView/organizational/agenciesManagement/index.vue
@@ -38,13 +38,13 @@
      </el-form-item>
    </el-form>
    <div class="gd-table-container" v-loading="loading">
    <div class="gd-table-toolbar">
      <el-button :icon="Plus" color="#4C34FF" type="primary" @click="openForm('add')">新增机构</el-button>
      <el-button :icon="Upload" @click="handleImport">机构导入</el-button>
      <el-button :icon="Download" :loading="exportLoading" :disabled="exportLoading" @click="handleExport">机构导出</el-button>
    </div>
    <div class="gd-table-container" v-loading="loading">
      <div class="gd-table-content gd-table-content-bg">
        <el-table class="gd-table" :data="list" @selection-change="handleSelectionChange">
          <el-table-column type="selection" width="46" />
applications/task-work-order/src/views/orderView/organizational/roleMange/index.vue
@@ -27,6 +27,7 @@
            </el-form-item>
        </el-form>
        <div class="gd-table-container" v-loading="loading" element-loading-background="rgba(5, 5, 15, 0.6)">
        <div class="gd-table-toolbar">
            <el-button :icon="Plus" color="#4C34FF" type="primary" @click="handleAdd">新增</el-button>
            <el-button :icon="Delete"  :disabled="!selectedIds.length" @click="handleDelete()">
@@ -41,7 +42,6 @@
            </el-button>
        </div>
        <div class="gd-table-container" v-loading="loading" element-loading-background="rgba(5, 5, 15, 0.6)">
            <div class="gd-table-content gd-table-content-bg">
                <el-table
                    class="gd-table"
applications/task-work-order/src/views/orderView/organizational/userMange/index.vue
@@ -108,7 +108,7 @@
    deptId: '',
    current: 1,
    size: 10,
    // sysType: 6
    sysType: 6
})
const searchParams = ref(initSearchParams())
@@ -133,7 +133,7 @@
        const res = await getUserList(
            searchParams.value.current,
            searchParams.value.size,
            // searchParams.value.sysType,
            searchParams.value.sysType,
            {
                account: searchParams.value.account,
                realName: searchParams.value.realName,
applications/task-work-order/src/views/orderView/organizational/zoningManagement/index.vue
@@ -37,13 +37,13 @@
      </el-form-item>
    </el-form>
    <div class="gd-table-container" v-loading="loading">
    <div class="gd-table-toolbar">
      <el-button :icon="Plus" color="#4C34FF" type="primary" @click="openForm('add')">新增区划</el-button>
      <el-button :icon="Upload" @click="handleImport">区划导入</el-button>
      <el-button :icon="Download" :loading="exportLoading" :disabled="exportLoading" @click="handleExport">区划导出</el-button>
    </div>
    <div class="gd-table-container" v-loading="loading">
      <div class="gd-table-content gd-table-content-bg">
        <el-table class="gd-table" :data="list" @selection-change="handleSelectionChange">
          <el-table-column type="selection" width="46" />
uniapps/work-app/src/hooks/useGlobalWS.js
@@ -10,8 +10,22 @@
  const callStatus = ref(null)
  // token 存储
  const accessToken = ref('')
  // 断线恢复定时器
  let recoverTimer = null
  // 存储铃声实例
  let ringtoneInstance = null
  // 监听WebView消息事件
  if (typeof uni !== 'undefined' && uni.$on) {
    uni.$on('webViewMessage', (data) => {
      console.log('📨 useGlobalWS 收到 WebView 消息:', data)
      // 处理挂断消息
      if (data?.type === 'hangupVoice') {
        console.log('📞 收到挂断消息')
        initWS()
      }
    });
  }
  // 设置默认用户ID为3
  const defaultUserId = '2021474815063486465';
@@ -150,11 +164,53 @@
  // }
  // 初始化WebSocket连接
  function isVoiceCallDetailActive() {
    try {
      const pages = getCurrentPages()
      const currentPage = pages[pages.length - 1]
      const route = currentPage?.route || currentPage?.$page?.fullPath || ''
      return String(route).includes('subPackages/voiceCallDetail/index')
    } catch (error) {
      return false
    }
  }
  function shouldRecoverWS() {
    return !isVoiceCallDetailActive() && !!useUserStore()?.userInfo?.access_token
  }
  function ensureRecoverTimer() {
    if (recoverTimer) {
      return
    }
    recoverTimer = setInterval(() => {
      // console.log('shouldRecoverWS()',shouldRecoverWS(),'----------',websocketService.getConnected())
      if (shouldRecoverWS() && !websocketService.getConnected()) {
        initWS()
      }
    }, 3000)
  }
  function initWS() {
    websocketService.close()
    const userStore = useUserStore()
    accessToken.value =userStore?.userInfo.access_token
    if (!accessToken.value || isVoiceCallDetailActive()) {
      return
    }
    try {
      websocketService.setOnMessageCallback(messageHandler);
      websocketService.setOnOpenCallback(() => {})
      websocketService.setOnCloseCallback(() => {
        if (shouldRecoverWS()) {
          ensureRecoverTimer()
        }
      })
      websocketService.setOnErrorCallback(() => {
        if (shouldRecoverWS()) {
          ensureRecoverTimer()
        }
      })
      // 获取当前用户ID,优先使用store中的用户信息
      const userId = userStore.userInfo?.new_userInfo.userId || defaultUserId;
@@ -165,9 +221,6 @@
        // 使用用户ID初始化WebSocket连接
        websocketService.init(userId, WS_BASE, accessToken.value);
        // console.log('🌐 全局WebSocket初始化成功,用户ID:', userId);
      } else {
        websocketService.connect();
      }
    } catch (error) {
    }
@@ -183,6 +236,8 @@
    },
    { immediate: true, deep: true }
  )
  ensureRecoverTimer()
}
uniapps/work-app/src/subPackages/voiceCallDetail/index.vue
@@ -79,9 +79,9 @@
function onPostMessage(data) {
    // 将WebView消息传递给全局WebSocket处理
    // if (typeof uni !== 'undefined' && uni.$emit) {
    //     uni.$emit('webViewMessage', data);
    // }
    if (typeof uni !== 'undefined' && uni.$emit) {
        uni.$emit('webViewMessage', data);
    }
}
</script>
uniapps/work-app/src/utils/websocket.js
@@ -114,8 +114,8 @@
    this.socketTask.send({
      data: JSON.stringify(message),
      success: () => {
        // console.log('WebSocket消息发送成功:', message)
        useGlobalWS();
        console.log('WebSocket消息发送成功:', message)
        // useGlobalWS();
      },
      fail: (error) => {
        // console.error('WebSocket消息发送失败:', error)
@@ -124,15 +124,15 @@
  }
  // 开始心跳检测
  startPing() {
    this.stopPing()
    // 每25秒发送一次心跳
    this.pingTimer = setInterval(() => {
      if (this.connected) {
        this.send('ping', 'system')
      }
    }, 25000)
  }
  // startPing() {
  //   this.stopPing()
  //   // 每25秒发送一次心跳
  //   this.pingTimer = setInterval(() => {
  //     if (this.connected) {
  //       this.send('ping', 'system')
  //     }
  //   }, 25000)
  // }
  // 停止心跳检测
  stopPing() {