【类 型】:feat

【原  因】:1.需要新增一个页面来添加和编辑无人机机型  2.飞机增删 添加了bind_class_id关联机型字段
【过  程】:1。新建了 PlaneClassAdd.vue 页面,支持根据路由参数判断是添加还是编辑模式;添加了表单项、按钮逻辑、初始化流程等功能,并接入 Vuex 的 planeClassList 和提交接口 2.飞机增删 添加了新字段 做相应处理
【影  响】:支持通过表单新增或修改无人机机型

# 类型 包含:
# feat:新功能(feature)
# fix:修补bug
# docs:文档(documentation)
# style: 格式(不影响代码运行的变动)
# refactor:重构(即不是新增功能,也不是修改bug的代码变动)
# test:增加测试
# chore:构建过程或辅助工具的变动
This commit is contained in:
air 2025-06-19 15:14:48 +08:00
parent 178219ea08
commit c8da790f64
5 changed files with 180 additions and 145 deletions

View File

@ -976,6 +976,8 @@ export default {
* @param {*} item 对应下拉框的任务
*/
isWaring (item) {
console.error('当前飞机ID', item.total_weight)
const isOverWaight = Number(item.total_weight) >= Number(this.plane.weight_max)//
const isQuestIng = (item.runing ?? '').split(',').some(i => i !== '') //
return isOverWaight || isQuestIng

View File

@ -367,16 +367,13 @@ const store = new Vuex.Store({
params.append('shop_id', form.shop_id)
params.append('name', form.name)
params.append('date', form.date)
if (form.onoff) {
params.append('onoff', '1')
} else {
params.append('onoff', '0')
}
params.append('weight_max', form.weight_max)
params.append('onoff', form.onoff ? '1' : '0')
params.append('desc', form.desc)
params.append('bind_class_id', form.bind_class_id) // ✅ 添加机型绑定字段
const res = await api.post('addAir', params)
if (res.data.status === 1) {
await dispatch('fetchAirList')// 刷新飞机列表
await dispatch('fetchAirList')
Message.success(res.data.msg)
} else {
Message.error(res.data.msg)
@ -393,17 +390,14 @@ const store = new Vuex.Store({
params.append('shop_id', form.shop_id)
params.append('name', form.name)
params.append('date', form.date)
if (form.onoff) {
params.append('onoff', '1')
} else {
params.append('onoff', '0')
}
params.append('weight_max', form.weight_max)
params.append('onoff', form.onoff ? '1' : '0')
params.append('desc', form.desc)
params.append('id', form.id)
params.append('bind_class_id', form.bind_class_id) // ✅ 添加机型绑定字段
const res = await api.post('saveAir', params)
if (res.data.status === 1) {
await dispatch('fetchAirList')// 刷新飞机列表
await dispatch('fetchAirList')
Message.success(res.data.msg)
} else {
Message.error(res.data.msg)
@ -467,6 +461,7 @@ const store = new Vuex.Store({
const res = await api.post('addPlaneClass', params)
if (res.data.status === 1) {
await dispatch('fetchPlaneClassList')// 刷新 机型列表
await dispatch('fetchAirList')// 刷新飞机列表
Message.success(res.data.msg)
} else {
Message.error(res.data.msg)
@ -485,17 +480,45 @@ const store = new Vuex.Store({
params.append('class_name', form.class_name)
params.append('wheelbase', form.wheelbase)
params.append('category', form.category)
params.append('weight_max', form.weight_max)
params.append('describe', form.describe)
const res = await api.post('savePlaneClass', params)
if (res.data.status === 1) {
await dispatch('fetchPlaneClassList')// 刷新 机型列表
await dispatch('fetchAirList')// 刷新飞机列表
Message.success(res.data.msg)
} else {
Message.error(res.data.msg)
}
return res
},
/**
* @description: 删除指定序号 机型
* @param {*} idArray 机型序号数组
*/
fetchDelPlaneClass ({ dispatch }, idArr) {
if (idArr.length === 0) {
Message.error('未勾选记录')
} else {
MessageBox.confirm('请谨慎操作 确认删除?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
const params = new URLSearchParams()
params.append('idArr', idArr)
api.post('deletePlaneClass', params).then(res => {
if (res.data.status === 1) {
Message.success(res.data.msg)
dispatch('fetchPlaneClassList')// 刷新 机型列表
} else {
Message.error(res.data.msg)
}
})
}).catch(() => {
Message.info('取消操作')
})
}
},
/**
* @description: 获取站点列表
*/

View File

@ -97,6 +97,7 @@ export default {
}
},
computed: {
//
planeClassList () {
return this.$store.state.planeClassList || []
}
@ -122,7 +123,7 @@ export default {
if (this.planeClass) {
this.setForm({ ...this.planeClass })
} else {
this.$message.error('找不到对应机型信息')
this.$message.warning('找不到对应机型信息')
}
}
},

View File

@ -1,75 +1,54 @@
<template>
<div class="app-container">
<!-- 组合按钮 -->
<el-button-group class="m-r-20 m-b-20">
<el-button type="primary" icon="el-icon-plus" @click="$router.replace('/register/add')">添加</el-button>
<el-button type="danger" icon="el-icon-delete" @click="deleteAir(countSelIdArr($refs.myTable.selection))">删除
<el-button-group>
<el-button type="primary" icon="el-icon-plus" @click="$router.replace('/model/add')">添加</el-button>
<el-button type="danger" icon="el-icon-delete" @click="deletePlaneClass(countSelIdArr($refs.myTable.selection))">删除
</el-button>
<el-button type="warning" icon="el-icon-edit" @click="toEditPage()">编辑</el-button>
<el-button type="success" icon="el-icon-data-line" @click="toFlyDataPage(countSelIdArr($refs.myTable.selection))">飞行数据</el-button>
</el-button-group>
<!-- 用户select选项 -->
<el-button-group class="m-b-20">
<el-button-group class="m-l-20">
<SelectionShopId v-model="form.shop_id" :allSel="true" />
</el-button-group>
<!-- 飞机表格 -->
<el-table class="w-100" ref="myTable"
:data="airListArr.slice((currentPage - 1) * pageSize, currentPage * pageSize)" border tooltip-effect="dark">
<!-- 站点表格 -->
<el-table class="m-t-20 w-100" ref="myTable"
:data="classListArr.slice((currentPage - 1) * pageSize, currentPage * pageSize)" border tooltip-effect="dark">
<el-table-column align="center" type="selection" width="40">
</el-table-column>
<el-table-column align="center" prop="id" label="id" width="50">
</el-table-column>
<el-table-column prop="name" label="名称" width="150" min-width="150">
<el-table-column prop="class_name" label="机型名称" width="120" min-width="100">
</el-table-column>
<el-table-column label="macID" width="175" min-width="175">
<template slot-scope="scope">
<el-tag :type="scope.row.macadd !== '' ? 'success' : 'danger'">
<i style="" class="iconfont m-r-5 f-s-16 l-h-32"
:class="scope.row.macadd !== '' ? 'icon-jiekou' : 'icon-cuowu'"></i>
<font>{{ scope.row.macadd !== '' ? scope.row.macadd : '未对频' }}</font>
</el-tag>
</template>
<el-table-column prop="wheelbase" label="轴距" width="120" min-width="150">
</el-table-column>
<el-table-column label="状态" min-width="150" show-overflow-tooltip>
<template slot-scope="scope">
<el-tag :type="scope.row.onoff === '1' ? 'success' : 'danger'">
<i style="" class="iconfont m-r-5 f-s-16 l-h-32"
:class="scope.row.onoff === '1' ? 'icon-qiyong' : 'icon-ic_tingyong'"></i>
<font>{{ scope.row.onoff === '1' ? '启用' : '停用' }}</font>
</el-tag>
</template>
<el-table-column prop="category" label="机型类型" width="120" min-width="150">
</el-table-column>
<el-table-column label="注册时间" width="100" min-width="80">
<template slot-scope="scope">
{{ scope.row.apply_time | parseTime('{y}-{m}-{d}') }}
</template>
<el-table-column prop="weight_max" label="最大载重" width="120" min-width="150">
</el-table-column>
<el-table-column prop="controler" label="操作" width="380" min-width="380">
<el-table-column prop="describe" label="描述" min-width="80" show-overflow-tooltip>
</el-table-column>
<el-table-column prop="controler" label="操作" width="140" min-width="140">
<template slot-scope="scope">
<el-button-group>
<el-button type="primary" class="iconfont icon-youxishoubing"
@click="$router.replace(`/planes/index/${scope.row.id}/${scope.row.name}`)"><span
class="m-l-5">操作</span></el-button>
<el-button type="warning" icon="el-icon-edit"
@click="$router.replace(`/register/edit/${scope.row.id}`)">编辑</el-button>
<el-button type="danger" icon="el-icon-delete" @click="deleteAir([scope.row.id])">删除</el-button>
<el-button type="danger" icon="el-icon-delete" @click="deletePlaneClass([scope.row.id])">删除</el-button>
</el-button-group>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<el-pagination class="m-t-20" layout="prev, pager, next" :current-page.sync="currentPage" :page-size="pageSize"
:total="airListArr.length">
:total="classListArr.length">
</el-pagination>
</div>
</template>
<script>
import { parseTime, countSelIdArr } from '@/utils'
import { countSelIdArr } from '@/utils'
import SelectionShopId from '@/components/SelectionShopId'
export default {
name: 'Register',
name: 'Model',
data () {
return {
pageSize: 8, //
@ -83,19 +62,19 @@ export default {
SelectionShopId
},
computed: {
//
airList () {
return this.$store.state.airList
//
planeClassList () {
return this.$store.state.planeClassList || []
},
/**
* @description: 过滤掉 不对应客户的 飞机列表
* @return: 飞机列表
* @description: 过滤掉 不对应客户的 站点列表
* @return: 站点列表
*/
airListArr () {
classListArr () {
if (this.form.shop_id !== '') {
return this.airList.filter((item) => item.shop_id === this.form.shop_id)
return this.planeClassList.filter((item) => item.shop_id === this.form.shop_id)
} else {
return this.airList
return this.planeClassList
}
}
},
@ -111,28 +90,17 @@ export default {
this.$message.error('请选择一条需要编辑的记录')
break
case 1:
this.$router.push('/register/edit/' + selId['0'])
this.$router.push('/model/edit/' + selId['0'])
break
default:
this.$message.error('只能选择一条记录')
}
},
/**
* @description: 跳转到飞机数据统计页面
* @description: 删除机型
*/
toFlyDataPage (selIdArr) {
if (selIdArr.length === 0) {
this.$message.error('请选择至少一架飞机')
} else {
this.$store.commit('app/setToFlyDataIdArr', selIdArr)//
this.$router.push('/register/flyData/')
}
},
/**
* @description: 删除飞机
*/
deleteAir (idArr) {
this.$store.dispatch('fetchDelAir', idArr)
deletePlaneClass (idArr) {
this.$store.dispatch('fetchDelPlaneClass', idArr)
}
},
watch: {
@ -140,7 +108,6 @@ export default {
created () {
},
filters: {
parseTime,
countSelIdArr
}
}
@ -155,12 +122,8 @@ export default {
}
}
.no-wrap-btn-group {
white-space: nowrap;
/* 禁止换行 */
overflow-x: auto;
/* 超出时可横向滚动 */
.image-placeholder {
position: relative;
display: inline-block;
/* 或者用 flex 布局 */
}
</style>

View File

@ -3,46 +3,84 @@
<el-row class="m-t-0">
<el-col :span="24">
<el-container>
<!-- 顶部标题栏 -->
<el-header height="42px" class="l-h-42 p-l-10 p-r-10 border border-b-n">
<div class="l">
<!-- 根据 pageState 显示图标 -->
<i v-if="pageState === 'add'" class="el-icon-plus f-s-20"></i>
<i v-else class="el-icon-edit f-s-20"></i>
<font class="m-l-10 f-s-18 fb">{{ $route.meta.title }}</font>
</div>
</el-header>
<!-- 主体表单区域 -->
<el-main class="border p-20 m-b-20">
<el-form ref="form" :model="form" label-width="120px" :label-position="$store.state.app.isWideScreen?'top':'right'">
<el-form ref="form" :model="form" label-width="120px"
:label-position="$store.state.app.isWideScreen ? 'top' : 'right'">
<!-- 只有添加模式下显示选择商铺组件 -->
<el-form-item v-if="pageState === 'add'" label="所属商铺">
<SelectionShopId v-model="form.shop_id" />
</el-form-item>
<!-- 飞机名称 -->
<el-form-item label="飞机名称">
<el-input v-model="form.name" placeholder="起名可以是中文" />
</el-form-item>
<!-- 购买日期添加模式可选编辑模式禁用 -->
<el-form-item label="购买日期">
<el-date-picker v-if="pageState == 'add' ? true : false" v-model="form.date" type="date"
placeholder="选择日期" format="yyyy 年 MM 月 dd 日" value-format="timestamp">
</el-date-picker>
<el-date-picker v-else v-model="form.date" type="date" placeholder="选择日期" format="yyyy 年 MM 月 dd 日"
value-format="timestamp" disabled>
</el-date-picker>
<el-date-picker v-if="pageState === 'add'" v-model="form.date" type="date"
placeholder="选择日期" format="yyyy 年 MM 月 dd 日" value-format="timestamp" />
<el-date-picker v-else v-model="form.date" type="date"
placeholder="选择日期" format="yyyy 年 MM 月 dd 日" value-format="timestamp" disabled />
</el-form-item>
<el-form-item label="运载极限重量">
<el-input v-model="form.weight_max" placeholder="运载的重量上限">
<template slot="append"></template>
</el-input>
</el-form-item>
<el-form-item :label="form.onoff === true ? '启用' : '停用'">
<!-- 启用/停用开关 -->
<el-form-item :label="form.onoff ? '启用' : '停用'">
<el-switch v-model="form.onoff" />
</el-form-item>
<!-- 绑定机型下拉框 -->
<el-form-item label="绑定机型">
<el-select v-model="form.bind_class_id" placeholder="请选择机型">
<el-option
v-for="item in planeClassList"
:key="item.id"
:label="item.class_name"
:value="item.id"
/>
</el-select>
</el-form-item>
<!-- 选中机型后展示信息 -->
<el-form-item label="">
<el-descriptions v-if="selectedPlaneClass" title="机型信息" :column="3" border>
<el-descriptions-item label="最大载重">
{{ selectedPlaneClass.weight_max }} kg
</el-descriptions-item>
<el-descriptions-item label="轴距">
{{ selectedPlaneClass.wheelbase }} mm
</el-descriptions-item>
<el-descriptions-item label="类别">
{{ selectedPlaneClass.category }}
</el-descriptions-item>
</el-descriptions>
</el-form-item>
<!-- 飞机描述 -->
<el-form-item label="飞机描述">
<el-input v-model="form.desc" type="textarea" placeholder="描述备注,非必填" />
</el-form-item>
<el-form-item v-if="pageState == 'add' ? true : false">
<!-- 底部按钮添加 / 编辑分别处理 -->
<el-form-item v-if="pageState === 'add'">
<el-button type="primary" icon="el-icon-plus" @click="addAir">创建</el-button>
<el-button @click="setForm({ shop_id: form.shop_id })" class="iconfont icon-qingchu">
<font class="m-l-5">重填</font>
</el-button>
</el-form-item>
<el-form-item v-else>
<el-button type="primary" icon="el-icon-edit" @click="saveAir">更新</el-button>
</el-form-item>
@ -59,78 +97,86 @@ import SelectionShopId from '@/components/SelectionShopId'
export default {
name: 'RegisterAdd',
components: { SelectionShopId },
data () {
return {
//
form: {
shop_id: '',
name: '',
date: '',
onoff: true,
bind_class_id: '',
weight_max: '',
desc: ''
},
airId: this.$route.params.id, // get id
pageState: 'add', //
// ID
airId: this.$route.params.id,
// add edit
pageState: 'add',
//
plane: null
}
},
components: {
SelectionShopId
},
computed: {
//
// Vuex
airList () {
return this.$store.state.airList
return this.$store.state.airList || []
},
// Vuex
planeClassList () {
return this.$store.state.planeClassList || []
},
//
selectedPlaneClass () {
return this.planeClassList.find(item => item.id === this.form.bind_class_id) || null
}
},
methods: {
//
//
setForm (data) {
if (data.desc == null) {
data.desc = ''
}
this.form.shop_id = data.shop_id
this.form.name = data.name
this.form.date = data.date
this.form.onoff = data.onoff
this.form.weight_max = data.weight_max
this.form.desc = data.desc
this.form.shop_id = data.shop_id || ''
this.form.name = data.name || ''
this.form.date = data.date || ''
this.form.onoff = data.onoff !== undefined ? data.onoff : true
this.form.bind_class_id = data.bind_class_id || ''
this.form.weight_max = data.weight_max || ''
this.form.desc = data.desc || ''
if (Object.keys(data).length === 0) {
this.$message.warning('清空表单')
}
},
// or
//
initPage () {
if (this.airId === undefined) {
// ID
if (!this.airId) {
this.pageState = 'add'
} else {
this.pageState = 'edit'
this.plane = this.airList.find((item) => item.id === this.airId)
if (this.plane) {
const data = {
shop_id: this.plane.shop_id,
name: this.plane.name,
date: this.plane.apply_time + '000',
onoff: this.plane.onoff === '1',
weight_max: this.plane.weight_max,
desc: this.plane.describe
}
this.setForm(data)
//
const targetPlane = this.airList.find((item) => item.id === this.airId)
if (targetPlane) {
this.plane = targetPlane
this.setForm({
shop_id: targetPlane.shop_id,
name: targetPlane.name,
date: parseInt(targetPlane.apply_time + '000'), //
onoff: targetPlane.onoff === '1',
bind_class_id: targetPlane.bind_class_id,
weight_max: targetPlane.weight_max,
desc: targetPlane.describe
})
}
}
},
/**
* @description: 创建新飞机
*/
//
async addAir () {
const res = await this.$store.dispatch('fetchAddAir', this.form)
if (res.data.status === 1) {
this.$router.push('/register/index')
this.$router.push('/register/index') //
}
},
/**
* @description: 更新飞机
*/
//
async saveAir () {
this.form.id = this.airId
const res = await this.$store.dispatch('fetchSaveAir', this.form)
@ -139,15 +185,15 @@ export default {
}
}
},
watch: {
airList () {
this.initPage()//
async created () {
//
if (!this.planeClassList.length) {
await this.$store.dispatch('fetchPlaneClassList')
}
},
created () {
if (this.airList.length > 0) {
this.initPage()//
if (!this.airList.length) {
await this.$store.dispatch('fetchAirList') //
}
this.initPage()
}
}
</script>