Merge remote-tracking branch 'origin/master'
8 files modified
1 files added
| | |
| | | |
| | | #开发环境代理地址(推荐本地新建文件 .env.development.local 来进行覆盖) |
| | | # VITE_APP_URL = https://wrj.shuixiongit.com/api |
| | | VITE_APP_URL= http://192.168.1.204 |
| | | VITE_APP_URL= http://192.168.1.168 |
| | | |
| | | #新大屏地址 |
| | | VITE_APP_DASHBOARD_URL = 'https://wrj.shuixiongit.com/command-center-dashboard/' |
| | |
| | | import DevicePopup from './components/DevicePopup.vue' |
| | | import DronePopup from './components/DronePopup.vue' |
| | | import { |
| | | RING_STYLES, |
| | | addDeviceRings, |
| | | createDroneTrackMaterial, |
| | | createRadialGradientMaterial, |
| | | getTexturedVertexFormat, |
| | | } from './device-map-materials' |
| | | import { getPointPositionsHeight } from '@/utils/cesium/mapUtil' |
| | | import { createDeviceRangePrimitiveWithHeight } from '@/utils/cesium/deviceRange' |
| | | import dzIcon from '@/assets/images/dataCockpit/map/dz-map-layer.png' |
| | | import yxIcon from '@/assets/images/dataCockpit/map/yx-map-layer.png' |
| | | |
| | |
| | | if (!Number.isFinite(range) || range <= 0) return null |
| | | return range |
| | | } |
| | | |
| | | |
| | | const ensureCockpitPrimitiveLayer = () => { |
| | | if (!viewer) return |
| | |
| | | reorderCockpitPrimitives() |
| | | } |
| | | |
| | | const renderDeviceEntities = devices => { |
| | | const renderDeviceEntities = async devices => { |
| | | if (!viewer) return |
| | | ensureCockpitPrimitiveLayer() |
| | | ensureDeviceCollections() |
| | |
| | | } |
| | | devicePickMap.clear() |
| | | deviceBillboardCollection.show = detailVisible.value |
| | | const ringFillInstancesByStyle = RING_STYLES.map(() => []) |
| | | const ringOutlineInstancesByStyle = RING_STYLES.map(() => []) |
| | | const deviceEntries = [] |
| | | const devicePositions = [] |
| | | devices.forEach((item, index) => { |
| | | const position = getDevicePosition(item) |
| | | if (!position) return |
| | | const entityId = `online-device-${item.id ?? index}-${index}` |
| | | const rangeMeters = getDeviceRange(item) |
| | | addDeviceRings(position, ringFillInstancesByStyle, ringOutlineInstancesByStyle, rangeMeters) |
| | | devicePositions.push({ lng: position.longitude, lat: position.latitude }) |
| | | const billboard = deviceBillboardCollection.add({ |
| | | position: Cesium.Cartesian3.fromDegrees(position.longitude, position.latitude, 0), |
| | | image: equipmentIcon, |
| | |
| | | }) |
| | | billboard.id = entityId |
| | | devicePickMap.set(entityId, { data: item, billboard }) |
| | | deviceEntries.push({ position, rangeMeters, billboard }) |
| | | }) |
| | | if (selectedTargetType.value === 'device' && selectedDeviceBillboard && !devicePickMap.has(selectedDeviceBillboard.id)) { |
| | | closePopup() |
| | | } |
| | | ringFillInstancesByStyle.forEach((instances, index) => { |
| | | if (!instances.length) return |
| | | const ring = RING_STYLES[index] |
| | | const alpha = ring.alpha ?? 0.64 |
| | | const innerRatio = |
| | | typeof ring.innerRatio === 'number' |
| | | ? ring.innerRatio |
| | | : ring.inner && ring.outer |
| | | ? Math.min(Math.max(ring.inner / ring.outer, 0), 0.9) |
| | | : 0 |
| | | const material = createRadialGradientMaterial( |
| | | Cesium.Color.fromCssColorString(ring.gradient[0]).withAlpha(alpha), |
| | | Cesium.Color.fromCssColorString(ring.gradient[1]).withAlpha(alpha), |
| | | { |
| | | gamma: 1.7, |
| | | innerCutoff: innerRatio, |
| | | if (deviceEntries.length) { |
| | | const heights = await getPointPositionsHeight(devicePositions, viewer) |
| | | deviceEntries.forEach((entry, index) => { |
| | | const height = Number(heights?.[index]?.ASL) |
| | | const centerHeight = Number.isFinite(height) ? height : 0 |
| | | if (entry.billboard) { |
| | | entry.billboard.position = Cesium.Cartesian3.fromDegrees( |
| | | entry.position.longitude, |
| | | entry.position.latitude, |
| | | centerHeight |
| | | ) |
| | | } |
| | | ) |
| | | const primitive = new Cesium.GroundPrimitive({ |
| | | geometryInstances: instances, |
| | | appearance: new Cesium.MaterialAppearance({ |
| | | material, |
| | | translucent: true, |
| | | }), |
| | | if (!Number.isFinite(entry.rangeMeters) || entry.rangeMeters <= 0) return |
| | | const primitive = createDeviceRangePrimitiveWithHeight(entry.position, entry.rangeMeters, centerHeight) |
| | | if (!primitive) return |
| | | primitive.show = detailVisible.value |
| | | addCockpitPrimitive(primitive) |
| | | deviceRingFillPrimitives.push(primitive) |
| | | }) |
| | | primitive.show = detailVisible.value |
| | | addCockpitPrimitive(primitive) |
| | | deviceRingFillPrimitives.push(primitive) |
| | | }) |
| | | ringOutlineInstancesByStyle.forEach(instances => { |
| | | if (!instances.length) return |
| | | const primitive = new Cesium.GroundPolylinePrimitive({ |
| | | geometryInstances: instances, |
| | | appearance: new Cesium.PolylineColorAppearance(), |
| | | }) |
| | | primitive.show = detailVisible.value |
| | | addCockpitPrimitive(primitive) |
| | | deviceRingOutlinePrimitives.push(primitive) |
| | | }) |
| | | } |
| | | reorderCockpitPrimitives() |
| | | } |
| | | |
| New file |
| | |
| | | import * as Cesium from 'cesium' |
| | | import { getPointPositionsHeight } from './mapUtil' |
| | | |
| | | const DEVICE_RANGE_MATERIAL_TYPE = 'DeviceRangeEllipsoid' |
| | | let deviceRangeMaterialRegistered = false |
| | | |
| | | export const registerDeviceRangeMaterial = () => { |
| | | if (deviceRangeMaterialRegistered || !Cesium?.Material) return |
| | | deviceRangeMaterialRegistered = true |
| | | Cesium.Material._materialCache.addMaterial(DEVICE_RANGE_MATERIAL_TYPE, { |
| | | fabric: { |
| | | type: DEVICE_RANGE_MATERIAL_TYPE, |
| | | uniforms: { |
| | | color: new Cesium.Color(1.0, 0.0, 0.0, 0.7), |
| | | speed: 3.0, |
| | | globalAlpha: 0.9 |
| | | }, |
| | | source: ` |
| | | uniform vec4 color; |
| | | uniform float speed; |
| | | uniform float globalAlpha; |
| | | |
| | | czm_material czm_getMaterial(czm_materialInput materialInput) |
| | | { |
| | | czm_material material = czm_getDefaultMaterial(materialInput); |
| | | vec2 st = materialInput.st; |
| | | |
| | | float time = fract(czm_frameNumber * speed / 1000.0); |
| | | |
| | | if (st.t < 0.5) { |
| | | discard; |
| | | } |
| | | |
| | | float alphaMars3D = abs(smoothstep(0.5, 1.0, fract(-st.t - time))); |
| | | alphaMars3D += 0.1; |
| | | |
| | | material.alpha = alphaMars3D * globalAlpha; |
| | | material.diffuse = color.rgb; |
| | | |
| | | return material; |
| | | } |
| | | `, |
| | | }, |
| | | translucent: () => true, |
| | | }) |
| | | } |
| | | |
| | | export const createDeviceRangeMaterial = () => { |
| | | registerDeviceRangeMaterial() |
| | | return Cesium.Material.fromType(DEVICE_RANGE_MATERIAL_TYPE, { |
| | | color: Cesium.Color.fromBytes(0, 255, 255, 155), |
| | | }) |
| | | } |
| | | |
| | | export const getDeviceLngLat = device => { |
| | | const lngRaw = device?.longitude ?? device?.lng ?? device?.lon |
| | | const latRaw = device?.latitude ?? device?.lat |
| | | const lng = Number(lngRaw) |
| | | const lat = Number(latRaw) |
| | | if (!Number.isFinite(lng) || !Number.isFinite(lat)) return null |
| | | return { lng, lat } |
| | | } |
| | | |
| | | export const normalizeDeviceRange = value => { |
| | | const range = Number(value) |
| | | if (!Number.isFinite(range) || range <= 0) return 2000 |
| | | return range |
| | | } |
| | | |
| | | export const resolveDeviceTerrainHeight = async (viewer, position) => { |
| | | if (!viewer || !position) return 0 |
| | | const lng = position.lng ?? position.longitude |
| | | const lat = position.lat ?? position.latitude |
| | | if (!Number.isFinite(Number(lng)) || !Number.isFinite(Number(lat))) return 0 |
| | | try { |
| | | const results = await getPointPositionsHeight([{ lng: Number(lng), lat: Number(lat) }], viewer) |
| | | const height = Number(results?.[0]?.ASL) |
| | | return Number.isFinite(height) ? height : 0 |
| | | } catch (error) { |
| | | return 0 |
| | | } |
| | | } |
| | | |
| | | export const createDeviceRangePrimitiveWithHeight = (position, rangeMeters, height, material = null) => { |
| | | if (!position || !Number.isFinite(rangeMeters)) return null |
| | | const lng = position.lng ?? position.longitude |
| | | const lat = position.lat ?? position.latitude |
| | | if (!Number.isFinite(Number(lng)) || !Number.isFinite(Number(lat))) return null |
| | | const center = Cesium.Cartesian3.fromDegrees(Number(lng), Number(lat), Number(height) || 0) |
| | | const radii = new Cesium.Cartesian3(rangeMeters, rangeMeters, rangeMeters) |
| | | const geometry = new Cesium.EllipsoidGeometry({ |
| | | radii, |
| | | vertexFormat: Cesium.MaterialAppearance.MaterialSupport.TEXTURED?.vertexFormat |
| | | || Cesium.VertexFormat.POSITION_AND_NORMAL, |
| | | }) |
| | | const instance = new Cesium.GeometryInstance({ |
| | | geometry, |
| | | modelMatrix: Cesium.Transforms.eastNorthUpToFixedFrame(center), |
| | | }) |
| | | return new Cesium.Primitive({ |
| | | geometryInstances: instance, |
| | | appearance: new Cesium.MaterialAppearance({ |
| | | material: material || createDeviceRangeMaterial(), |
| | | closed: true, |
| | | translucent: true, |
| | | flat: true, |
| | | faceForward: true, |
| | | }), |
| | | asynchronous: false |
| | | }) |
| | | } |
| | | |
| | | export const createDeviceRangePrimitive = async (viewer, position, rangeMeters, material = null) => { |
| | | if (!viewer) return null |
| | | const height = await resolveDeviceTerrainHeight(viewer, position) |
| | | return createDeviceRangePrimitiveWithHeight(position, rangeMeters, height, material) |
| | | } |
| | |
| | | import { fieldRules, geomAnalysis, getDictLabel } from '@ztzf/utils' |
| | | import CommonCesiumMap from '@/components/map-container/common-cesium-map.vue' |
| | | import { DrawManager, EditManager, buildEllipsePositions } from '@/utils/cesium/shapeTools' |
| | | import { cartesian3Convert, getPointPositionsHeight } from '@/utils/cesium/mapUtil' |
| | | import { cartesian3Convert } from '@/utils/cesium/mapUtil' |
| | | import { |
| | | createDeviceRangePrimitive, |
| | | getDeviceLngLat, |
| | | normalizeDeviceRange, |
| | | resolveDeviceTerrainHeight, |
| | | } from '@/utils/cesium/deviceRange' |
| | | import * as Cesium from 'cesium' |
| | | import { AREA_TYPE_STYLE_MAP, BUFFER_LEVEL_STYLES, DEFAULT_AREA_STYLE } from '@ztzf/constants' |
| | | import { fwPoliceStationListApi } from '@/views/areaManage/precinctInfo/precinctInfoApi' |
| | |
| | | let viewEntity |
| | | let shapeDisplaySource |
| | | const deviceRangePrimitiveMap = new Map() |
| | | let deviceRangeMaterialRegistered = false |
| | | const activeToolMode = ref('') |
| | | |
| | | const rules = { |
| | |
| | | return shapeDisplaySource |
| | | } |
| | | |
| | | function registerDeviceRangeMaterial () { |
| | | if (deviceRangeMaterialRegistered || !Cesium?.Material) return |
| | | deviceRangeMaterialRegistered = true |
| | | Cesium.Material._materialCache.addMaterial('DeviceRangeEllipsoid', { |
| | | fabric: { |
| | | type: 'DeviceRangeEllipsoid', |
| | | uniforms: { |
| | | color: new Cesium.Color(1.0, 0.0, 0.0, 0.7), |
| | | speed: 3.0, |
| | | }, |
| | | source: ` |
| | | uniform vec4 color; |
| | | uniform float speed; |
| | | czm_material czm_getMaterial(czm_materialInput materialInput){ |
| | | czm_material material = czm_getDefaultMaterial(materialInput); |
| | | vec2 st = materialInput.st; |
| | | float time = fract(czm_frameNumber * speed / 1000.0); |
| | | float alpha = abs(smoothstep(0.5,1.,fract( -st.t - time))); |
| | | alpha += .1; |
| | | material.alpha = alpha; |
| | | material.diffuse = color.rgb; |
| | | return material; |
| | | } |
| | | `, |
| | | }, |
| | | translucent: () => true, |
| | | }) |
| | | } |
| | | |
| | | function createDeviceRangeMaterial () { |
| | | registerDeviceRangeMaterial() |
| | | return Cesium.Material.fromType('DeviceRangeEllipsoid', { |
| | | color: Cesium.Color.fromBytes(0, 255, 255, 155), |
| | | }) |
| | | } |
| | | |
| | | function clearDeviceRangePrimitives () { |
| | | if (!viewer || !deviceRangePrimitiveMap.size) return |
| | | for (const primitive of deviceRangePrimitiveMap.values()) { |
| | |
| | | deviceRangePrimitiveMap.clear() |
| | | } |
| | | |
| | | function normalizeDeviceRange (value) { |
| | | const range = Number(value) |
| | | if (!Number.isFinite(range) || range <= 0) return 2000 |
| | | return range |
| | | } |
| | | |
| | | function getDeviceLngLat (device) { |
| | | const lngRaw = device?.longitude ?? device?.lng ?? device?.lon |
| | | const latRaw = device?.latitude ?? device?.lat |
| | | const lng = Number(lngRaw) |
| | | const lat = Number(latRaw) |
| | | if (!Number.isFinite(lng) || !Number.isFinite(lat)) return null |
| | | return { lng, lat } |
| | | } |
| | | |
| | | async function resolveDeviceTerrainHeight (position) { |
| | | if (!viewer) return 0 |
| | | try { |
| | | const results = await getPointPositionsHeight([{ lng: position.lng, lat: position.lat }], viewer) |
| | | const height = Number(results?.[0]?.ASL) |
| | | return Number.isFinite(height) ? height : 0 |
| | | } catch (error) { |
| | | return 0 |
| | | } |
| | | } |
| | | |
| | | async function createDeviceRangePrimitive (device) { |
| | | if (!viewer) return null |
| | | if (!device) return null |
| | | const position = getDeviceLngLat(device) |
| | | if (!position) return null |
| | | const rangeMeters = normalizeDeviceRange(device.effectiveRangeKm) |
| | | const centerHeight = await resolveDeviceTerrainHeight(position) |
| | | const center = Cesium.Cartesian3.fromDegrees(position.lng, position.lat, centerHeight) |
| | | const radii = new Cesium.Cartesian3(rangeMeters, rangeMeters, rangeMeters) |
| | | const geometry = new Cesium.EllipsoidGeometry({ |
| | | radii, |
| | | vertexFormat: Cesium.MaterialAppearance.MaterialSupport.TEXTURED?.vertexFormat |
| | | || Cesium.VertexFormat.POSITION_AND_NORMAL, |
| | | }) |
| | | const instance = new Cesium.GeometryInstance({ |
| | | geometry, |
| | | modelMatrix: Cesium.Transforms.eastNorthUpToFixedFrame(center), |
| | | }) |
| | | return new Cesium.Primitive({ |
| | | geometryInstances: instance, |
| | | appearance: new Cesium.MaterialAppearance({ |
| | | material: createDeviceRangeMaterial(), |
| | | closed: true, |
| | | translucent: true, |
| | | flat: true, |
| | | faceForward: true, |
| | | }), |
| | | asynchronous: false |
| | | }) |
| | | } |
| | | |
| | | async function renderDeviceRangeSingle (device) { |
| | | if (!viewer) return |
| | | clearDeviceRangePrimitives() |
| | | const primitive = await createDeviceRangePrimitive(device) |
| | | const position = getDeviceLngLat(device) |
| | | if (!position) return |
| | | const rangeMeters = normalizeDeviceRange(device.effectiveRangeKm) |
| | | const primitive = await createDeviceRangePrimitive(viewer, position, rangeMeters) |
| | | if (!primitive) return |
| | | deviceRangePrimitiveMap.set(String(device?.id ?? Date.now()), primitive) |
| | | viewer.scene.primitives.add(primitive) |
| | |
| | | if (!pendingRows.length) return |
| | | const primitives = await Promise.all( |
| | | pendingRows.map(async row => { |
| | | const primitive = await createDeviceRangePrimitive(row) |
| | | const position = getDeviceLngLat(row) |
| | | if (!position) return { row, primitive: null } |
| | | const rangeMeters = normalizeDeviceRange(row.effectiveRangeKm) |
| | | const primitive = await createDeviceRangePrimitive(viewer, position, rangeMeters) |
| | | return { row, primitive } |
| | | }) |
| | | ) |
| | |
| | | if (!viewer) return |
| | | const position = getDeviceLngLat(device) |
| | | if (!position) return |
| | | const height = await resolveDeviceTerrainHeight(position) |
| | | const destination = Cesium.Cartesian3.fromDegrees(position.lng, position.lat, height + device.effectiveRangeKm * 3) |
| | | const height = await resolveDeviceTerrainHeight(viewer, position) |
| | | const rangeMeters = normalizeDeviceRange(device?.effectiveRangeKm) |
| | | const destination = Cesium.Cartesian3.fromDegrees(position.lng, position.lat, height + rangeMeters * 3) |
| | | viewer.camera.flyTo({ |
| | | destination, |
| | | orientation: { |
| | |
| | | <el-table-column type="selection" width="46" /> |
| | | <el-table-column type="index" show-overflow-tooltip width="64" label="序号" /> |
| | | <el-table-column prop="areaName" show-overflow-tooltip width="150" label="区域名称" /> |
| | | <el-table-column prop="areaTypeKeys" show-overflow-tooltip width="120" label="区域类型"> |
| | | <el-table-column prop="areaTypeKeys" show-overflow-tooltip width="196" label="区域类型"> |
| | | <template v-slot="{ row }"> |
| | | {{ getDictLabel(row.areaTypeKeys, dictObj.areaType) }} |
| | | </template> |
| | |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="policeStationName" show-overflow-tooltip label="关联派出所" /> |
| | | <el-table-column show-overflow-tooltip label="可飞行时间段"> |
| | | <el-table-column show-overflow-tooltip width="300" label="可飞行时间段"> |
| | | <template v-slot="{ row }"> |
| | | {{ formatFlyDate(row) }} |
| | | </template> |
| | |
| | | * @Author : yuan |
| | | * @Date : 2026-01-17 14:51:39 |
| | | * @LastEditors : yuan |
| | | * @LastEditTime : 2026-01-17 15:13:50 |
| | | * @LastEditTime : 2026-01-30 15:20:56 |
| | | * @FilePath : \applications\drone-command\src\views\dataCockpit\components\LegendBar.vue |
| | | * @Description : |
| | | * Copyright 2026 OBKoro1, All Rights Reserved. |
| | |
| | | <div class="legend-bar"> |
| | | <div class="legend-title" data-text="图例">图例</div> |
| | | <div class="legend-item"> |
| | | <span class="legend-color partition"></span> |
| | | <span class="legend-text" data-text="区域">区域</span> |
| | | <span class="legend-color detect-area"></span> |
| | | <span class="legend-text" data-text="侦测区">侦测区</span> |
| | | </div> |
| | | <div class="legend-item"> |
| | | <span class="legend-color alarm-area"></span> |
| | | <span class="legend-text" data-text="报警区">报警区</span> |
| | | </div> |
| | | <div class="legend-item"> |
| | | <span class="legend-color key-control-area"></span> |
| | | <span class="legend-text" data-text="重点管制区">重点管制区</span> |
| | | </div> |
| | | <div class="legend-item"> |
| | | <img class="legend-icon drone" :src="droneIcon" alt="无人机" /> |
| | |
| | | border: 1px solid rgba(255, 215, 114, 0.9); |
| | | } |
| | | |
| | | .legend-color.detect-area { |
| | | background-color: rgba(25, 178, 230, 0.5); |
| | | border: 1px solid rgb(0, 251, 255); |
| | | } |
| | | |
| | | .legend-color.alarm-area { |
| | | background-color: rgba(255, 235, 59, 0.5); |
| | | border: 1px solid rgb(255, 235, 59); |
| | | } |
| | | |
| | | .legend-color.key-control-area { |
| | | background-color: rgba(247, 20, 20, 0.5); |
| | | border: 1px solid rgb(255, 0, 0); |
| | | } |
| | | |
| | | .legend-icon { |
| | | width: 30px; |
| | | height: 42px; |
| | |
| | | </el-row> |
| | | </div> |
| | | <!-- 申请中--> |
| | | <div v-if="detailDemandStatus === '1' && !requesterProvider"> |
| | | <div v-if="detailDemandStatus === '1' && (permissionList.approvedBtn || permissionList.rejectBtn)"> |
| | | <div class="detail-title" :style="{ marginTop:pxToRem(10)}">数据上传</div> |
| | | <div class="upload-container"> |
| | | <el-upload |
| | |
| | | </div> |
| | | </div> |
| | | <template #footer> |
| | | <template v-if="detailDemandStatus === '1' && !requesterProvider"> |
| | | <el-button color="#F2F3F5" :loading="submitting || uploading" :disabled="submitting || uploading" @click="rejectTheApplication">拒绝申请</el-button> |
| | | <el-button class="" color="#4C34FF" :loading="submitting || uploading" :disabled="submitting || uploading" @click="approvedByTheReview">审核通过</el-button> |
| | | <template v-if="detailDemandStatus === '1' "> |
| | | <el-button v-if="permissionList.rejectBtn" color="#F2F3F5" :loading="submitting || uploading" :disabled="submitting || uploading" @click="rejectTheApplication">拒绝申请</el-button> |
| | | <el-button v-if="permissionList.approvedBtn" class="" color="#4C34FF" :loading="submitting || uploading" :disabled="submitting || uploading" @click="approvedByTheReview">审核通过</el-button> |
| | | </template> |
| | | <template v-if="detailDemandStatus === '2'"> |
| | | <el-button class="" color="#4C34FF" @click="downloadAllFiles">全部下载</el-button> |
| | | </template> |
| | | <template v-if="detailDemandStatus === '3'"> |
| | | <el-button class="" color="#4C34FF" @click="visible =false">关闭</el-button> |
| | | </template> |
| | | <!-- <template v-if="detailDemandStatus === '3'">--> |
| | | <!-- <el-button class="" color="#4C34FF" @click="visible =false">关闭</el-button>--> |
| | | <!-- </template>--> |
| | | </template> |
| | | </el-dialog> |
| | | |
| | |
| | | import AuditRecord from '@/views/orderView/orderDataManage/supplyAdd/auditRecord.vue' // 导入新组件 |
| | | import { useStore } from 'vuex' |
| | | const store = useStore() |
| | | const requesterProvider = computed(() => store.state.user.userInfo?.role_id === '2014158512610869250') |
| | | const permission = computed(() => store.state.user.permission); |
| | | const emit = defineEmits(['success']) |
| | | const dictObj = inject('dictObj') |
| | | const deptTree = inject('deptTree') |
| | |
| | | const responseData = ref(null) |
| | | const submitting = ref(false) // 提交中状态 |
| | | const uploading = ref(false) // 文件上传中状态 |
| | | function validData(value, defaultValue) { |
| | | return value !== undefined ? value : defaultValue |
| | | } |
| | | const permissionList = computed(() => { |
| | | return { |
| | | addBtn: validData(permission.value.orderData_addDemand, false), |
| | | rejectBtn: validData(permission.value.orderData_rejectApplication, false), |
| | | approvedBtn: validData(permission.value.orderData_approved, false), |
| | | } |
| | | }) |
| | | // 自定义上传请求函数 |
| | | const handleHttpRequest = async (options) => { |
| | | uploading.value = true |
| | |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <div class="gd-table-toolbar"> |
| | | <div class="gd-table-toolbar" v-if="permissionList.addBtn"> |
| | | <el-button :icon="Plus" color="#4C34FF" type="primary" @click="openForm('add')">供需填报新增</el-button> |
| | | </div> |
| | | |
| | |
| | | <el-table-column label="操作" class-name="operation-btns" width="150"> |
| | | <template v-slot="{ row }"> |
| | | <el-link type="primary" @click="openForm('view', row)">查看</el-link> |
| | | <!-- 只对非审批状态显示编辑和删除按钮 --> |
| | | <el-link type="primary" @click="openForm('edit', row)" v-if="!['1', '2', '3'].includes(row.demandStatus)">编辑</el-link> |
| | | <el-link type="primary" @click="handleDelete(row)" v-if="!['1', '2', '3'].includes(row.demandStatus)">删除</el-link> |
| | | <el-link type="primary" @click="openForm('edit', row)" v-if="!['1', '2', '3'].includes(row.demandStatus) && permissionList.addBtn">编辑</el-link> |
| | | <el-link type="primary" @click="handleDelete(row)" v-if="!['1', '2', '3'].includes(row.demandStatus) && permissionList.deleteBtn">删除</el-link> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | |
| | | gdSupplyDemandPageApi, |
| | | gdSupplyDemandRemoveApi, |
| | | } from '@/views/orderView/orderDataManage/supplyAdd/supplyAddApi' |
| | | |
| | | import { useStore } from 'vuex' |
| | | const store = useStore() |
| | | const permission = computed(() => store.state.user.permission); |
| | | // 初始化查询参数 |
| | | const initSearchParams = () => ({ |
| | | demandName: '', // 需求名称 |
| | |
| | | provide('detailDemandStatus', detailDemandStatus) |
| | | const reasonForRejection = ref('') //拒绝原因 |
| | | provide('reasonForRejection', reasonForRejection) |
| | | |
| | | function validData(value, defaultValue) { |
| | | return value !== undefined ? value : defaultValue |
| | | } |
| | | const permissionList = computed(() => { |
| | | return { |
| | | addBtn: validData(permission.value.orderData_addDemand, false), |
| | | deleteBtn: validData(permission.value.orderData_delete, false), |
| | | } |
| | | }) |
| | | |
| | | // 根据部门ID获取部门名称 |
| | | function getDeptNameById(deptId, deptList) { |
| | | if (!deptId || !Array.isArray(deptList)) return '' |
| | |
| | | }); |
| | | } |
| | | const loginFormGd = ref({ |
| | | username: "admin", |
| | | password: "admin", |
| | | username: "zhx", |
| | | password: "123456", |
| | | }); |
| | | async function submit() { |
| | | |