飞行器设备接口问题修复,涉及的飞行员,景区,区域均接入接口

This commit is contained in:
hr121 2025-07-23 15:33:43 +08:00
parent 465960a281
commit d671fecf5b
6 changed files with 508 additions and 262 deletions

View File

@ -35,6 +35,14 @@ export function edit(data) {
}) })
} }
// 获取飞行器设备详情
export function getDeviceDetail(id) {
return request({
url: `aerocraftAdminApi/aircraft/device/${id}`,
method: 'get'
})
}
// 分页查询飞行器维保记录 // 分页查询飞行器维保记录
export function getMaintenanceRecords(params) { export function getMaintenanceRecords(params) {
return request({ return request({
@ -87,4 +95,4 @@ export function editInsurance(data) {
}) })
} }
export default { get, del, add, edit, getMaintenanceRecords, getInsuranceRecords, addInsurance, getInsuranceDetail, deleteInsurance, editInsurance } export default { get, del, add, edit, getMaintenanceRecords, getInsuranceRecords, addInsurance, getInsuranceDetail, deleteInsurance, editInsurance, getDeviceDetail }

View File

@ -41,5 +41,21 @@ export function updatePass(user) {
}) })
} }
export default { add, edit, del } // 查询飞行员,飞行器管理要用到
export function getList(params) {
return request({
url: 'api/emEmployees/findByPage',
method: 'get',
params
})
}
export function getDetail(id) {
return request({
url: `api/emEmployees/${id}`,
method: 'get'
})
}
export default { add, edit, del, getList, getDetail }

View File

@ -1,7 +1,7 @@
<template> <template>
<el-card class="box-card"> <el-card class="box-card">
<div slot="header" class="clearfix"> <div slot="header" class="clearfix">
<span style="color: #027db4;">飞行器基本信息</span> <span style="color: #027db4">飞行器基本信息</span>
</div> </div>
<el-form :model="form" label-width="100px" class="detail-form"> <el-form :model="form" label-width="100px" class="detail-form">
<el-row :gutter="20"> <el-row :gutter="20">
@ -17,31 +17,31 @@
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="类型"> <el-form-item label="类型">
<el-input v-model="form.type" disabled /> <el-input v-model="form.useType" disabled />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="8"> <el-col :span="8">
<el-form-item label="区域"> <el-form-item label="区域">
<el-input v-model="form.region" disabled /> <el-input v-model="form.areaName" disabled />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="景区"> <el-form-item label="景区">
<el-input v-model="form.scenicArea" disabled /> <el-input v-model="form.scenicName" disabled />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="负责人"> <el-form-item label="负责人">
<el-input v-model="form.manager" disabled /> <el-input v-model="form.username" disabled />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row> <el-row>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="备注"> <el-form-item label="备注">
<el-input type="textarea" v-model="form.remarks" disabled /> <el-input type="textarea" v-model="form.remark" disabled />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
@ -49,8 +49,13 @@
<el-col :span="24"> <el-col :span="24">
<el-form-item label="无人机图片"> <el-form-item label="无人机图片">
<div class="image-preview"> <div class="image-preview">
<div v-for="(url, index) in form.imageUrls" :key="index" class="image-item" @click="handlePreview(url)"> <div
<img :src="url" class="preview-image"> v-for="image in form.deviceImages"
:key="image.id"
class="image-item"
@click="handlePreview(image.fileFullPath || image)"
>
<img :src="image.fileFullPath || image" class="preview-image" />
</div> </div>
</div> </div>
</el-form-item> </el-form-item>
@ -60,33 +65,33 @@
<!-- 图片预览 --> <!-- 图片预览 -->
<el-dialog :visible.sync="previewVisible" append-to-body> <el-dialog :visible.sync="previewVisible" append-to-body>
<img :src="previewUrl" alt="Preview" style="width: 100%"> <img :src="previewUrl" alt="Preview" style="width: 100%" />
</el-dialog> </el-dialog>
</el-card> </el-card>
</template> </template>
<script> <script>
export default { export default {
name: 'BasicInfo', name: "BasicInfo",
props: { props: {
form: { form: {
type: Object, type: Object,
required: true required: true,
} },
}, },
data() { data() {
return { return {
previewVisible: false, previewVisible: false,
previewUrl: '' previewUrl: "",
} };
}, },
methods: { methods: {
handlePreview(url) { handlePreview(url) {
this.previewUrl = url this.previewUrl = url;
this.previewVisible = true this.previewVisible = true;
} },
} },
} };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@ -115,7 +120,7 @@ export default {
border-radius: 4px; border-radius: 4px;
overflow: hidden; overflow: hidden;
&:hover { &:hover {
border-color: #409EFF; border-color: #409eff;
} }
.preview-image { .preview-image {
width: 100%; width: 100%;

View File

@ -140,13 +140,13 @@ export default {
required: true, required: true,
}, },
aircraftId: { aircraftId: {
type: [String, Number], type: String,
required: true required: true
} }
}, },
computed: { computed: {
...mapGetters([ ...mapGetters([
'fileUploadApi' 's3UploadApi'
]) ])
}, },
data() { data() {
@ -288,7 +288,7 @@ export default {
this.loading = true; this.loading = true;
try { try {
const res = await upload(this.fileUploadApi, file.raw); const res = await upload(this.s3UploadApi, file.raw);
if (res.status === 200) { if (res.status === 200) {
const data = res.data; const data = res.data;
// //
@ -302,7 +302,6 @@ export default {
fileFullPath: data.fileFullPath || `/file/${data.newFileName}`, fileFullPath: data.fileFullPath || `/file/${data.newFileName}`,
fileSize: file.raw.size, fileSize: file.raw.size,
fileType: file.raw.name.split('.').pop(), fileType: file.raw.name.split('.').pop(),
id: 0,
newFileName: data.newFileName, newFileName: data.newFileName,
sourceFileName: file.raw.name sourceFileName: file.raw.name
}); });
@ -341,7 +340,7 @@ export default {
if (valid) { if (valid) {
try { try {
const baseData = { const baseData = {
aircraftId: this.aircraftId || 0, // 0使 aircraftId: this.aircraftId,
name: this.form.name, name: this.form.name,
insuranceType: this.form.insuranceType, insuranceType: this.form.insuranceType,
deadlineTime: this.form.deadlineTime, deadlineTime: this.form.deadlineTime,

View File

@ -15,7 +15,7 @@
<insurance-record <insurance-record
:data="insuranceData" :data="insuranceData"
:page="insurancePage" :page="insurancePage"
:aircraft-id="Number($route.query.id)" :aircraft-id="String($route.query.id)"
@size-change="handleInsuranceSizeChange" @size-change="handleInsuranceSizeChange"
@current-change="handleInsuranceCurrentChange" @current-change="handleInsuranceCurrentChange"
@view="handleInsuranceView" @view="handleInsuranceView"
@ -31,7 +31,7 @@
<script> <script>
import { mapGetters } from 'vuex' import { mapGetters } from 'vuex'
import { getMaintenanceRecords, getInsuranceRecords } from '@/api/aircraft' import { getDeviceDetail, getMaintenanceRecords, getInsuranceRecords } from '@/api/aircraft'
import BasicInfo from './components/BasicInfo' import BasicInfo from './components/BasicInfo'
import MaintenanceRecord from './components/MaintenanceRecord' import MaintenanceRecord from './components/MaintenanceRecord'
import InsuranceRecord from './components/InsuranceRecord' import InsuranceRecord from './components/InsuranceRecord'
@ -49,12 +49,14 @@ export default {
form: { form: {
name: '大疆', name: '大疆',
model: 'T100', model: 'T100',
type: '载人飞行', useType: '载人飞行',
region: '北京', areaName: '北京',
scenicArea: '白云山', scenicName: '白云山',
manager: '小明', username: '小明',
remarks: '设备状态良好', remark: '设备状态良好',
imageUrls: Array(6).fill('https://axure-file.lanhuapp.com/md5__f344f816278c2a3f5164e4571c580ad9.png') deviceImages: [
'https://axure-file.lanhuapp.com/md5__f344f816278c2a3f5164e4571c580ad9.png'
]
}, },
maintenanceData: [], maintenanceData: [],
insuranceData: [], insuranceData: [],
@ -72,32 +74,57 @@ export default {
}, },
computed: { computed: {
...mapGetters([ ...mapGetters([
'fileUploadApi', 's3UploadApi',
'baseApi' 'baseApi'
]) ])
}, },
created() { created() {
const id = this.$route.query.id const id = this.$route.query.id
if (id) { const rowData = this.$route.query.data ? JSON.parse(this.$route.query.data) : null
if (rowData) {
this.getDetail(id, rowData)
}else {
this.getDetail(id) this.getDetail(id)
} }
this.loadMaintenanceRecords() this.loadMaintenanceRecords()
this.loadInsuranceRecords() this.loadInsuranceRecords()
}, },
methods: { methods: {
getDetail(id) { getDetail(id, rowData = null) {
console.log('获取详情:', id) getDeviceDetail(id).then(response => {
// this.loadInsuranceRecords() this.form = response
if (rowData) {
this.form.areaName = rowData.areaName
this.form.scenicName = rowData.scenicName
this.form.username = rowData.username
}
this.form.useType = this.form.useType === 0 ? '载物飞行' : this.form.useType === 1 ? '载人飞行' : '其他'
//
this.form.deviceImages = this.form.deviceImages.map((image, index) => {
if (typeof image === 'string') {
return {
id: String(index),
fileFullPath: image
}
}
return {
...image,
id: String(image.id || index)
}
});
}).catch(error => {
console.error('获取设备详情失败:', error)
this.$message.error('获取设备详情失败')
})
}, },
async loadInsuranceRecords() { async loadInsuranceRecords() {
try { try {
const params = { const params = {
aircraftId: this.$route.query.id || 0,// 0 aircraftId: this.$route.query.id,
current: this.insurancePage.current, current: this.insurancePage.current,
size: this.insurancePage.size size: this.insurancePage.size
} }
const response = await getInsuranceRecords(params) const response = await getInsuranceRecords(params)
console.log('保险记录:', response)
this.insuranceData = response.records this.insuranceData = response.records
this.insurancePage.total = response.total this.insurancePage.total = response.total
} catch (error) { } catch (error) {

View File

@ -3,61 +3,125 @@
<!--工具栏--> <!--工具栏-->
<div class="head-container"> <div class="head-container">
<div class="filter-container"> <div class="filter-container">
<el-input v-model="query.name" clearable size="small" placeholder="请输入飞行器名称" style="width: 200px;" class="filter-item" /> <el-input
<el-select v-model="query.employeesId" placeholder="请选择负责人" clearable size="small" style="width: 200px" class="filter-item"> v-model="query.name"
<el-option v-for="employee in employeeOptions" clearable
size="small"
placeholder="请输入飞行器名称"
style="width: 200px"
class="filter-item"
/>
<el-select
v-model="query.employeesId"
placeholder="请选择负责人"
clearable
size="small"
style="width: 200px"
class="filter-item"
>
<el-option
v-for="employee in employeeOptions"
:key="employee.id" :key="employee.id"
:label="employee.name" :label="employee.name"
:value="employee.id" /> :value="employee.id"
/>
</el-select> </el-select>
<el-select v-model="query.areaId" placeholder="请选择区域" clearable size="small" style="width: 200px" class="filter-item"> <el-select
<el-option v-for="area in areaOptions" v-model="query.areaId"
placeholder="请选择区域"
size="small"
style="width: 200px"
class="filter-item"
>
<el-option
v-for="area in areaOptions"
:key="area.id" :key="area.id"
:label="area.name" :label="area.name"
:value="area.id" /> :value="area.id"
/>
</el-select> </el-select>
<el-button class="filter-item" size="small" type="primary" icon="el-icon-search" @click="crud.toQuery">查询</el-button> <el-button
<el-button v-permission="permission.add" class="filter-item" size="small" type="success" icon="el-icon-plus" @click="crud.toAdd" v-if="checkPer(permission.add)">新增飞行器</el-button> class="filter-item"
size="small"
type="primary"
icon="el-icon-search"
@click="crud.toQuery"
>查询</el-button
>
<el-button
v-permission="permission.add"
class="filter-item"
size="small"
type="success"
icon="el-icon-plus"
@click="crud.toAdd"
v-if="checkPer(permission.add)"
>新增飞行器</el-button
>
</div> </div>
</div> </div>
<!--表单渲染--> <!--表单渲染-->
<el-dialog append-to-body :close-on-click-modal="false" :before-close="crud.cancelCU" :visible.sync="crud.status.cu > 0" :title="crud.status.title" width="580px"> <el-dialog
<el-form ref="form" :inline="true" :model="form" :rules="rules" size="small" label-width="100px"> append-to-body
:close-on-click-modal="false"
:before-close="crud.cancelCU"
:visible.sync="crud.status.cu > 0"
:title="crud.status.title"
width="580px"
>
<el-form
ref="form"
:inline="true"
:model="form"
:rules="rules"
size="small"
label-width="100px"
>
<el-form-item label="飞行器名称" prop="name"> <el-form-item label="飞行器名称" prop="name">
<el-input v-model="form.name" style="width: 150px;" /> <el-input v-model="form.name" style="width: 150px" />
</el-form-item> </el-form-item>
<el-form-item label="型号" prop="model"> <el-form-item label="型号" prop="model">
<el-input v-model="form.model" style="width: 150px;" /> <el-input v-model="form.model" style="width: 150px" />
</el-form-item> </el-form-item>
<el-form-item label="类型" prop="useType"> <el-form-item label="类型" prop="useType">
<el-select v-model="form.useType" style="width: 150px;"> <el-select v-model="form.useType" style="width: 150px">
<el-option :value="0" label="载物飞行" /> <el-option :value="0" label="载物飞行" />
<el-option :value="1" label="载人飞行" /> <el-option :value="1" label="载人飞行" />
<el-option :value="2" label="其他" /> <el-option :value="2" label="其他" />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="区域" prop="areaId"> <el-form-item label="区域" prop="areaId">
<el-select v-model="form.areaId" style="width: 150px;"> <el-select
<el-option v-for="area in areaOptions" v-model="form.areaId"
@change="changeArea"
style="width: 150px"
>
<el-option
v-for="area in areaOptions"
:key="area.id" :key="area.id"
:label="area.name" :label="area.name"
:value="area.id" /> :value="area.id"
/>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="景区" prop="scenicId"> <el-form-item label="景区" prop="scenicId">
<el-select v-model="form.scenicId" style="width: 150px;"> <el-select v-model="form.scenicId" style="width: 150px">
<el-option v-for="scenic in scenicOptions" <el-option
v-for="scenic in scenicOptions"
:key="scenic.id" :key="scenic.id"
:label="scenic.name" :label="scenic.name"
:value="scenic.id" /> :value="scenic.id"
/>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="角色" prop="employeesId"> <el-form-item label="负责人" prop="employeesId">
<el-select v-model="form.employeesId" style="width: 150px;"> <el-select v-model="form.employeesId" style="width: 150px">
<el-option v-for="employee in employeeOptions" <el-option
v-for="employee in employeeOptions"
:key="employee.id" :key="employee.id"
:label="employee.name" :label="employee.name"
:value="employee.id" /> :value="employee.id"
/>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="备注" prop="remarks" :label-width="'100px'"> <el-form-item label="备注" prop="remarks" :label-width="'100px'">
@ -66,23 +130,46 @@
:rows="2" :rows="2"
placeholder="请输入备注" placeholder="请输入备注"
v-model="form.remarks" v-model="form.remarks"
style="width: 150px;"> style="width: 150px"
>
</el-input> </el-input>
</el-form-item> </el-form-item>
<el-form-item label="设备图片" prop="deviceImages" style="width: 100%;"> <el-form-item label="设备图片" prop="deviceImages" style="width: 100%">
<div class="upload-container"> <div class="upload-container">
<el-upload ref="uploadRef" action="#" list-type="picture-card" <el-upload
:show-file-list="false" :on-change="handleChange" :auto-upload="false" accept="image/*" ref="uploadRef"
:class="{ 'upload-item': true }"> action="#"
<div style="display: flex;flex-direction: column;align-items: center;justify-content: center;margin-top: -20px;"> list-type="picture-card"
<i class="el-icon-plus" style="font-size: 30px;" /> :show-file-list="false"
<span style="margin: 5px 0 -20px;line-height: 20px">上传</span> :on-change="handleChange"
:auto-upload="false"
accept="image/*"
:class="{ 'upload-item': true }"
>
<div
style="
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin-top: -20px;
"
>
<i class="el-icon-plus" style="font-size: 30px" />
<span style="margin: 5px 0 -20px; line-height: 20px">上传</span>
</div> </div>
</el-upload> </el-upload>
<div v-for="(image, index) in form.deviceImages" :key="index" class="preview-item"> <div
<img :src="image.fileFullPath" class="preview-image" alt=""> v-for="(image, index) in form.deviceImages"
:key="index"
class="preview-item"
>
<img :src="image.fileFullPath" class="preview-image" alt="" />
<span class="preview-actions"> <span class="preview-actions">
<span class="preview-action" @click="handlePictureCardPreview(image.fileFullPath)"> <span
class="preview-action"
@click="handlePictureCardPreview(image.fileFullPath)"
>
<i class="el-icon-zoom-in" /> <i class="el-icon-zoom-in" />
</span> </span>
<span class="preview-action" @click="handleRemoveImage(index)"> <span class="preview-action" @click="handleRemoveImage(index)">
@ -93,14 +180,23 @@
</div> </div>
<el-dialog append-to-body :visible.sync="dialogVisible" top="20vh"> <el-dialog append-to-body :visible.sync="dialogVisible" top="20vh">
<div> <div>
<img :src="dialogImageUrl" style="width: 100%" alt="Preview Image"> <img
:src="dialogImageUrl"
style="width: 100%"
alt="Preview Image"
/>
</div> </div>
</el-dialog> </el-dialog>
</el-form-item> </el-form-item>
</el-form> </el-form>
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
<el-button type="text" @click="crud.cancelCU">取消</el-button> <el-button type="text" @click="crud.cancelCU">取消</el-button>
<el-button :loading="crud.status.cu === 2" type="primary" @click="crud.submitCU">确认</el-button> <el-button
:loading="crud.status.cu === 2"
type="primary"
@click="crud.submitCU"
>确认</el-button
>
</div> </div>
</el-dialog> </el-dialog>
<!--表格渲染--> <!--表格渲染-->
@ -118,20 +214,22 @@
<el-table-column label="型号" prop="model" /> <el-table-column label="型号" prop="model" />
<el-table-column label="类型" prop="useType"> <el-table-column label="类型" prop="useType">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.useType === 0 ? '载物' : scope.row.useType === 1 ? '载人' : '其他' }} {{
scope.row.useType === 0
? "载物行动"
: scope.row.useType === 1
? "载人行动"
: "其他"
}}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="负责人" prop="employeeName" /> <el-table-column label="负责人" prop="username" />
<el-table-column label="区域" prop="areaName" /> <el-table-column label="区域" prop="areaName" />
<el-table-column label="景区" prop="scenicName" /> <el-table-column label="景区" prop="scenicName" />
<el-table-column label="创建时间" prop="createTime" width="180" /> <el-table-column label="创建时间" prop="createTime" width="180" />
<el-table-column label="操作" width="150" align="center" fixed="right"> <el-table-column label="操作" width="150" align="center" fixed="right">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button <el-button size="mini" type="text" @click="handleView(scope.row)">
size="mini"
type="text"
@click="handleView(scope.row)"
>
查看 查看
</el-button> </el-button>
<el-button <el-button
@ -172,18 +270,18 @@
</template> </template>
<script> <script>
import CRUD, { presenter, header, form, crud } from '@crud/crud' import CRUD, { presenter, header, form, crud } from "@crud/crud";
import udOperation from '@crud/UD.operation' import udOperation from "@crud/UD.operation";
import crudAircraft from '@/api/aircraft' import crudAircraft from "@/api/aircraft";
import { allAreas } from '@/api/system/area' import { allAreas } from "@/api/system/area";
import { getAll } from '@/api/system/role' import { getList, getDetail } from "@/api/system/pilot";
import { allScenic } from '@/api/system/scenic' import { allScenic } from "@/api/system/scenic";
import { upload } from '@/utils/upload' import { upload } from "@/utils/upload";
import { mapGetters } from 'vuex' import { mapGetters } from "vuex";
import rrOperation from '@crud/RR.operation' import rrOperation from "@crud/RR.operation";
// crudpresenter // crudpresenter
const defaultForm = { const defaultForm = {
id: 0, id: 1,
name: null, name: null,
brand: null, brand: null,
model: null, model: null,
@ -192,268 +290,359 @@ const defaultForm = {
scenicId: null, scenicId: null,
employeesId: null, employeesId: null,
deviceImages: [], deviceImages: [],
remark: '', remark: "",
createTime: null createTime: null,
} };
export default { export default {
name: 'aircraft', name: "aircraft",
components: { udOperation }, components: { udOperation },
cruds() { cruds() {
return CRUD({ return CRUD({
title: '飞行器', title: "飞行器",
url: 'aerocraftAdminApi/aircraft/device', url: "aerocraftAdminApi/aircraft/device/page",
crudMethod: { crudMethod: {
...crudAircraft, ...crudAircraft,
getList: crudAircraft.getDevicePage getList: crudAircraft.getDevicePage,
}, },
optShow: { optShow: {
search: true search: true,
}, },
queryOnPresenterCreated: false, // queryOnPresenterCreated: true, //
page: {
//
page: "current",
size: "size",
},
//
query: { query: {
current: 1,
size: 10,
employeesId: undefined, employeesId: undefined,
areaId: undefined, areaId: undefined,
name: undefined name: undefined,
},
initData: (crud, data) => {
crud.page.total = data.total;
// id
const records = data.records || [];
crud.data = records.map(item => ({
...item,
id: item.id ? item.id.toString() : ''
}));
// usernamegetList()
crud.data.forEach((item) => {
if (item.employeesId) {
getList().then((res) => {
res.content.forEach((employee) => {
if (employee.id === item.employeesId) {
item.username = employee.username;
} }
}) });
});
} else {
item.username = "未知";
}
});
},
});
}, },
mixins: [presenter(), header(), form(defaultForm), crud()], mixins: [presenter(), header(), form(defaultForm), crud()],
data() { data() {
return { return {
dialogVisible: false, dialogVisible: false,
dialogImageUrl: '', dialogImageUrl: "",
uploadDisabled: false, uploadDisabled: false,
// ini // ini
page: { page: {
page: 1, page: 1,
size: 10, size: 10,
total: 5 total: 5,
}, },
areaOptions: [], areaOptions: [],
scenicOptions: [], scenicOptions: [],
employeeOptions: [], employeeOptions: [],
// //
query: { query: {
name: '', name: "",
employeesId: undefined, employeesId: undefined,
areaId: undefined, areaId: undefined,
current: 1, current: 1,
size: 10 size: 10,
}, },
defaultData: [{ defaultData: [],
id: 1,
name: '无人机01',
brand: 'DJI',
model: 'Mavic Air 2',
useType: 0,
employeesId: 1,
employeeName: '张三',
areaId: 1,
areaName: '北京',
scenicId: 1,
scenicName: '故宫',
createTime: '2025-07-17 08:50:08',
deviceImages: [{
fileFullPath: 'https://example.com/image1.jpg',
fileSize: 102400,
fileType: 'jpg',
id: 1,
newFileName: 'drone_20250717.jpg',
sourceFileName: 'DJI_0001.jpg'
}]
}],
permission: { permission: {
add: ['admin', 'aircraft:add'], add: ["admin", "aircraft:add"],
edit: ['admin', 'aircraft:edit'], edit: ["admin", "aircraft:edit"],
del: ['admin', 'aircraft:del'] del: ["admin", "aircraft:del"],
}, },
rules: { rules: {
name: [ name: [
{ required: true, message: '请输入飞行器名称', trigger: 'blur' } { required: true, message: "请输入飞行器名称", trigger: "blur" },
],
brand: [
{ required: true, message: '品牌不能为空', trigger: 'blur' }
],
model: [
{ required: true, message: '请输入型号', trigger: 'blur' }
],
useType: [
{ required: true, message: '请选择类型', trigger: 'change' }
],
areaId: [
{ required: true, message: '请选择区域', trigger: 'change' }
], ],
brand: [{ required: true, message: "品牌不能为空", trigger: "blur" }],
model: [{ required: true, message: "请输入型号", trigger: "blur" }],
useType: [{ required: true, message: "请选择类型", trigger: "change" }],
areaId: [{ required: true, message: "请选择区域", trigger: "change" }],
scenicId: [ scenicId: [
{ required: true, message: '请选择景区', trigger: 'change' } { required: true, message: "请选择景区", trigger: "change" },
], ],
employeesId: [ employeesId: [
{ required: true, message: '请选择负责人', trigger: 'change' } { required: true, message: "请选择负责人", trigger: "change" },
], ],
deviceImages: [ deviceImages: [
{ required: true, message: '请上传设备图片', trigger: 'change', type: 'array' } {
] required: true,
} message: "请上传设备图片",
} trigger: "change",
type: "array",
},
],
},
};
}, },
computed: { computed: {
...mapGetters([ ...mapGetters(["imagesUploadApi", "baseApi"]),
'imagesUploadApi',
'baseApi'
])
}, },
created() { created() {
// //
this.getAreas() this.getAreas();
//
this.getScenics()
// //
this.getEmployees() this.getEmployees();
}, },
methods: { methods: {
// //
async getAreas() { async getAreas() {
try { try {
const res = await allAreas() const res = await allAreas();
if (res) { if (res) {
this.areaOptions = res this.areaOptions = res.map((area) => ({
id: area.id,
name: area.name,
}));
} }
} catch (error) { } catch (error) {
this.$message.error('获取区域列表失败') this.$message.error("获取区域列表失败");
console.error('获取区域列表失败:', error) console.error("获取区域列表失败:", error);
this.areaOptions = [] this.areaOptions = [];
} }
}, },
// //
async getScenics() { changeArea(value) {
try { //
const res = await allScenic() this.query.scenicId = undefined;
//
allScenic({ areaId: value }).then((res) => {
if (res) { if (res) {
this.scenicOptions = res this.scenicOptions = (res || []).map((scenic) => ({
} id: scenic.id,
} catch (error) { name: scenic.name,
this.$message.error('获取景区列表失败') }));
console.error('获取景区列表失败:', error) } else {
this.scenicOptions = [] this.scenicOptions = [];
} }
});
}, },
// //
async getEmployees() { async getEmployees() {
try { try {
const res = await getAll() const res = await getList();
if (res) { if (res) {
this.employeeOptions = res this.employeeOptions = res.content.map((employee) => ({
id: employee.id,
name: employee.username,
}));
} }
} catch (error) { } catch (error) {
this.$message.error('获取角色列表失败') this.$message.error("获取负责人列表失败");
console.error('获取角色列表失败:', error) console.error("获取负责人列表失败:", error);
this.employeeOptions = [] this.employeeOptions = [];
} }
}, },
[CRUD.HOOK.beforeToEdit](crud, form) {
//
if (form.areaId) {
allScenic({ areaId: form.areaId }).then((res) => {
if (res) {
this.scenicOptions = (res || []).map((scenic) => ({
id: scenic.id,
name: scenic.name,
}));
} else {
this.scenicOptions = [];
}
});
} else {
this.scenicOptions = [];
}
//
if (form.employeesId) {
getList().then((res) => {
if (res) {
this.employeeOptions = res.content.map((employee) => ({
id: employee.id,
name: employee.username,
}));
} else {
this.employeeOptions = [];
}
});
} else {
this.employeeOptions = [];
}
},
[CRUD.HOOK.beforeSubmit]() { [CRUD.HOOK.beforeSubmit]() {
// brandname // brandname
this.form.brand = this.form.name this.form.brand = this.form.name;
return true return true;
}, },
[CRUD.HOOK.beforeRefresh]() { [CRUD.HOOK.beforeRefresh]() {
//
// if (!this.query.employeesId) {
// this.$message.warning('')
// return false
// }
// //
this.query.current = this.page.page this.crud.params.current = this.page.page;
this.query.size = this.page.size this.crud.params.size = this.page.size;
return true
//
this.crud.params.employeesId = this.query.employeesId;
this.crud.params.areaId = this.query.areaId;
this.crud.params.name = this.query.name;
return true;
}, },
[CRUD.HOOK.afterRefresh]() { [CRUD.HOOK.afterRefresh]() {
// //
if (this.crud.data.total) { const response = this.crud.data;
this.page.total = this.crud.data.total
if (response) {
// total
if (response.total !== undefined) {
this.page.total = response.total;
} }
// // records
if (Array.isArray(this.crud.data)) { if (response && Array.isArray(response)) {
this.crud.data = [...this.defaultData, ...this.crud.data] // Promise
// const detailPromises = response.map(item => {
this.page.total += this.defaultData.length if (!item || !item.id) return Promise.resolve(null);
} else if (this.crud.data && this.crud.data.records) { const stringId = item.id.toString();
this.crud.data.records = [...this.defaultData, ...this.crud.data.records] return crudAircraft.getDeviceDetail(stringId).then(res => {
// if (!res) return null;
this.page.total += this.defaultData.length return {
...item,
...res,
id: stringId
};
});
});
//
Promise.all(detailPromises).then(detailedData => {
// id
this.crud.data = detailedData.filter(item => item && item.id && typeof item.id === 'string');
}).catch(error => {
console.error('获取设备详情失败:', error);
this.$message.error('获取设备详情失败');
});
} else {
// records,
this.crud.data = [];
}
} else {
// ,
this.crud.data = [];
this.page.total = 0;
} }
}, },
handleView(row) { handleView(row) {
this.$router.push({ path: '/aircraft/aircraftDetail', query: { id: row.id }}) const tempRow = { areaName: row.areaName, scenicName: row.scenicName, username: row.username };
this.$router.push({
path: "/system/aircraftDetail/index",
query: {
id: row.id,
data: JSON.stringify(tempRow)
}, },
});
},
//
handlePictureCardPreview(url) { handlePictureCardPreview(url) {
this.dialogImageUrl = url this.dialogImageUrl = url;
this.dialogVisible = true this.dialogVisible = true;
}, },
// //
handleRemoveImage(index) { handleRemoveImage(index) {
this.form.deviceImages.splice(index, 1) this.form.deviceImages.splice(index, 1);
}, },
// //
handleChange(file, uploadFiles) { handleChange(file, uploadFiles) {
if (file.raw.type.includes('image')) { if (file.raw.type.includes("image")) {
this.loading = true this.loading = true;
try { try {
upload(this.imagesUploadApi, file.raw).then(res => { upload(this.imagesUploadApi, file.raw).then((res) => {
if(res.status === 200){ if (res.status === 200) {
const data = res.data; const data = res.data;
// deviceImages // deviceImages
const deviceImage = { const deviceImage = {
fileFullPath: this.baseApi + `/file/图片/` + data.newFileName, fileFullPath: data.fileFullPath,
fileSize: file.raw.size, fileSize: file.raw.size,
fileType: file.raw.type.split('/')[1], fileType: file.raw.type.split("/")[1],
id: 0,
newFileName: data.newFileName, newFileName: data.newFileName,
sourceFileName: file.raw.name sourceFileName: file.raw.name,
}; };
// //
if (!this.form.deviceImages) { if (!this.form.deviceImages) {
this.form.deviceImages = []; this.form.deviceImages = [];
} }
this.form.deviceImages.push(deviceImage); this.form.deviceImages.push(deviceImage);
this.$message.success('图片上传成功!') this.$message.success("图片上传成功!");
this.loading = false; this.loading = false;
}else{ } else {
this.$message.error('图片上传失败!'); this.$message.error("图片上传失败!");
this.loading = false; this.loading = false;
return; return;
} }
}); });
} catch (error) { } catch (error) {
this.loading = false this.loading = false;
this.$message.error('图片上传失败!') this.$message.error("图片上传失败!");
} }
} else { } else {
this.$confirm('图片的格式不正确,请重新选择!', '提示', { this.$confirm("图片的格式不正确,请重新选择!", "提示", {
confirmButtonText: '确定', confirmButtonText: "确定",
type: 'warning' type: "warning",
}) });
uploadFiles.pop() uploadFiles.pop();
} }
}, },
handleDelete(row) { handleDelete(row) {
this.$confirm(`此操作将永久删除飞行器"${row.name}",是否继续?`, '提示', { this.$confirm(`此操作将永久删除飞行器"${row.name}",是否继续?`, "提示", {
confirmButtonText: '确定', confirmButtonText: "确定",
cancelButtonText: '取消', cancelButtonText: "取消",
type: 'warning' type: "warning",
}).then(() => { })
this.crud.toDelete(row.id) .then(() => {
}).catch(() => { crudAircraft.del(row.id).then(() => {
this.$notify({
title: "成功",
type: "success",
message: "删除成功!",
});
this.crud.refresh();
});
})
.catch(() => {
this.$message({ this.$message({
type: 'info', type: "info",
message: '已取消删除' message: "已取消删除",
}) });
}) });
} },
} },
} };
</script> </script>
<style rel="stylesheet/scss" lang="scss" scoped> <style rel="stylesheet/scss" lang="scss" scoped>
@ -537,11 +726,13 @@ export default {
.app-container { .app-container {
padding-bottom: 60px; padding-bottom: 60px;
} }
::v-deep .el-input-number .el-input__inner { ::v-deep .el-input-number .el-input__inner {
text-align: left; text-align: left;
} }
::v-deep .vue-treeselect__control,::v-deep .vue-treeselect__placeholder,::v-deep .vue-treeselect__single-value { ::v-deep .vue-treeselect__control,
::v-deep .vue-treeselect__placeholder,
::v-deep .vue-treeselect__single-value {
height: 30px; height: 30px;
line-height: 30px; line-height: 30px;
} }
</style> </style>