499 lines
15 KiB
Vue
499 lines
15 KiB
Vue
<template>
|
||
<div class="pump-form">
|
||
<el-dialog
|
||
v-model="state.isShowDialog"
|
||
destroy-on-close
|
||
:title="props.title"
|
||
draggable
|
||
:close-on-click-modal="false"
|
||
:close-on-press-escape="false"
|
||
width="900px"
|
||
>
|
||
<el-form ref="pumpFormRef" :model="state.ruleForm" :rules="state.ruleRules" label-width="120px">
|
||
|
||
<!-- 基本信息 -->
|
||
<div class="form-section">
|
||
<div class="section-title">基本信息</div>
|
||
|
||
<el-row :gutter="25">
|
||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
|
||
<el-form-item label="设备编号" prop="deviceNo" required>
|
||
<el-input v-model="state.ruleForm.deviceNo" placeholder="请输入设备编号" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
|
||
<el-form-item label="资产编号" prop="assetNo" required>
|
||
<el-input v-model="state.ruleForm.assetNo" placeholder="请输入资产编号" />
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
|
||
<el-row :gutter="25">
|
||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
|
||
<el-form-item label="设备型号" prop="model" required>
|
||
<el-select
|
||
v-model="state.ruleForm.model"
|
||
placeholder="请选择设备型号"
|
||
style="width: 100%"
|
||
filterable
|
||
allow-create
|
||
>
|
||
<el-option
|
||
v-for="model in state.modelOptions"
|
||
:key="model.value"
|
||
:label="model.name"
|
||
:value="model.value"
|
||
/>
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
|
||
<el-form-item label="规格" prop="specification" required>
|
||
<el-input v-model="state.ruleForm.specification" placeholder="请输入设备规格" />
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
|
||
<el-row :gutter="25">
|
||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
|
||
<el-form-item label="设备负责人" prop="principalId" required>
|
||
<el-select
|
||
v-model="state.ruleForm.principalId"
|
||
placeholder="请选择设备负责人"
|
||
clearable
|
||
filterable
|
||
style="width: 100%"
|
||
>
|
||
<el-option
|
||
v-for="user in state.userOptions"
|
||
:key="user.id"
|
||
:label="`${user.name} (${user.userName})`"
|
||
:value="user.id"
|
||
/>
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
</div>
|
||
|
||
<!-- 技术参数 -->
|
||
<div class="form-section">
|
||
<div class="section-title">技术参数</div>
|
||
|
||
<el-row :gutter="25">
|
||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
|
||
<el-form-item label="工作泵速(g/min)" prop="workingSpeed" required>
|
||
<el-input-number
|
||
v-model="state.ruleForm.workingSpeed"
|
||
:min="0"
|
||
:precision="2"
|
||
style="width: 100%"
|
||
placeholder="请输入工作泵速"
|
||
/>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
|
||
<el-form-item label="时长:(s)" prop="workingTime" required>
|
||
<el-input-number
|
||
v-model="state.ruleForm.workingTime"
|
||
:min="0"
|
||
style="width: 100%"
|
||
placeholder="请输入超时时间"
|
||
/>
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
|
||
<el-row :gutter="25">
|
||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
|
||
<el-form-item label="泵速系数" prop="speedCoefficient" required>
|
||
<el-input-number
|
||
v-model="state.ruleForm.speedCoefficient"
|
||
:min="0"
|
||
:precision="3"
|
||
style="width: 100%"
|
||
placeholder="请输入泵速系数"
|
||
/>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
|
||
<el-form-item label="维护状态" prop="maintenanceFlag">
|
||
<el-select
|
||
v-model="state.ruleForm.maintenanceFlag"
|
||
placeholder="请选择维护状态"
|
||
style="width: 100%"
|
||
>
|
||
<el-option
|
||
v-for="status in state.maintenanceStatusOptions"
|
||
:key="status.value"
|
||
:label="status.label"
|
||
:value="status.value"
|
||
/>
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
</div>
|
||
|
||
<!-- 网络配置 -->
|
||
<div class="form-section">
|
||
<div class="section-title">网络配置</div>
|
||
|
||
<el-row :gutter="25">
|
||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
|
||
<el-form-item label="IP地址" prop="ip" required>
|
||
<el-input v-model="state.ruleForm.ip" placeholder="请输入IP地址" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
|
||
<el-form-item label="端口号" prop="port" required>
|
||
<el-input v-model="state.ruleForm.port" placeholder="请输入端口号" />
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
|
||
<el-row :gutter="25">
|
||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
|
||
<el-form-item label="服务名称" prop="serviceName">
|
||
<el-input v-model="state.ruleForm.serviceName" placeholder="请输入服务名称" />
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
</div>
|
||
</el-form>
|
||
|
||
<template #footer>
|
||
<span class="dialog-footer">
|
||
<el-button @click="onCancel">取消</el-button>
|
||
<el-button type="primary" @click="onSubmit" :loading="state.loading">确定</el-button>
|
||
</span>
|
||
</template>
|
||
</el-dialog>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts" name="PumpForm">
|
||
import { reactive, ref, getCurrentInstance, onMounted } from 'vue'
|
||
import { PumpApi } from '/@/api/admin/PumpApi'
|
||
import { UserApi } from '/@/api/admin/User'
|
||
import { FeedingConfigApi } from '/@/api/admin/FeedingConfigApi'
|
||
import { DictApi } from '/@/api/admin/Dict'
|
||
import { UserGetPageOutput, PageInputUserGetPageInput, PumpAddInput, PumpUpdateInput, FeedingConfigGetListOutput, DictGetListOutput } from '/@/api/admin/data-contracts'
|
||
import eventBus from '/@/utils/mitt'
|
||
|
||
// 定义父组件传过来的值
|
||
const props = defineProps({
|
||
title: String,
|
||
})
|
||
|
||
// 定义子组件向父组件传值/事件
|
||
const emit = defineEmits(['refresh'])
|
||
|
||
// 定义变量内容
|
||
const pumpFormRef = ref()
|
||
const { proxy } = getCurrentInstance() as any
|
||
|
||
// 临时类型定义
|
||
type PumpFormData = {
|
||
id?: number
|
||
deviceNo: string
|
||
assetNo: string
|
||
model: string
|
||
specification: string
|
||
pumpSpeed: number
|
||
principalId: number | undefined
|
||
pumpTimeout: number
|
||
maintenanceFlag: number
|
||
ip: string
|
||
port: string
|
||
speedCoefficient: number
|
||
serviceName: string
|
||
isAirPump: boolean
|
||
configId: number | undefined,
|
||
workingSpeed: number,
|
||
workingTime: number,
|
||
}
|
||
|
||
const state = reactive({
|
||
isShowDialog: false,
|
||
loading: false,
|
||
configLoading: false,
|
||
ruleForm: {
|
||
id: undefined,
|
||
deviceNo: '',
|
||
assetNo: '',
|
||
model: '',
|
||
specification: '',
|
||
pumpSpeed: 0,
|
||
workingSpeed: 0,
|
||
workingTime: 0,
|
||
principalId: undefined,
|
||
pumpTimeout: 0,
|
||
maintenanceFlag: 1,
|
||
ip: '',
|
||
port: '',
|
||
speedCoefficient: 0,
|
||
serviceName: '',
|
||
isAirPump: false,
|
||
configId: undefined,
|
||
} as PumpFormData,
|
||
userOptions: [] as Array<UserGetPageOutput>,
|
||
configOptions: [] as Array<FeedingConfigGetListOutput>,
|
||
modelOptions: [] as Array<DictGetListOutput>,
|
||
maintenanceStatusOptions: [
|
||
{ label: 'Offline', value: 0 },
|
||
{ label: 'Idle', value: 1 },
|
||
{ label: 'Busy', value: 2 },
|
||
{ label: 'Error', value: 3 },
|
||
],
|
||
ruleRules: {
|
||
deviceNo: [
|
||
{ required: true, message: '设备编号不能为空', trigger: 'blur' },
|
||
{ min: 1, max: 50, message: '设备编号长度应在1-50个字符', trigger: 'blur' }
|
||
],
|
||
assetNo: [
|
||
{ required: true, message: '资产编号不能为空', trigger: 'blur' },
|
||
{ min: 1, max: 50, message: '资产编号长度应在1-50个字符', trigger: 'blur' }
|
||
],
|
||
model: [{ required: true, message: '设备型号不能为空', trigger: 'change' }],
|
||
specification: [
|
||
{ required: true, message: '规格不能为空', trigger: 'blur' },
|
||
{ min: 1, max: 100, message: '规格长度应在1-100个字符', trigger: 'blur' }
|
||
],
|
||
principalId: [{ required: true, message: '设备负责人不能为空', trigger: 'change' }],
|
||
pumpSpeed: [{ required: true, message: '泵速不能为空', trigger: 'blur' }],
|
||
pumpTimeout: [{ required: true, message: '超时时间不能为空', trigger: 'blur' }],
|
||
workingSpeed: [{ required: true, message: '工作泵速不能为空', trigger: 'blur' }],
|
||
workingTime: [{ required: true, message: '时长不能为空', trigger: 'blur' }],
|
||
speedCoefficient: [{ required: true, message: '泵速系数不能为空', trigger: 'blur' }],
|
||
ip: [
|
||
{ required: true, message: 'IP地址不能为空', trigger: 'blur' },
|
||
{ pattern: /^((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$/, message: '请输入正确的IP地址格式', trigger: 'blur' }
|
||
],
|
||
port: [
|
||
{ required: true, message: '端口号不能为空', trigger: 'blur' },
|
||
{ pattern: /^([0-9]|[1-9]\d{1,3}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])$/, message: '请输入正确的端口号(1-65535)', trigger: 'blur' }
|
||
],
|
||
},
|
||
})
|
||
|
||
onMounted(() => {
|
||
getUserOptions()
|
||
getConfigOptions()
|
||
getModelOptions()
|
||
})
|
||
|
||
// 打开弹窗
|
||
const openDialog = async (row?: any) => {
|
||
resetForm()
|
||
|
||
// 确保用户数据已加载
|
||
if (state.userOptions.length === 0) {
|
||
await getUserOptions()
|
||
}
|
||
|
||
// 确保配置数据已加载
|
||
if (state.configOptions.length === 0) {
|
||
await getConfigOptions()
|
||
}
|
||
|
||
// 确保设备型号数据已加载
|
||
if (state.modelOptions.length === 0) {
|
||
await getModelOptions()
|
||
}
|
||
|
||
if (row && row.id) {
|
||
// 编辑模式,获取详情
|
||
try {
|
||
const res = await new PumpApi().get({ id: row.id })
|
||
if (res?.success && res.data) {
|
||
state.ruleForm = {
|
||
id: res.data.id,
|
||
deviceNo: res.data.deviceNo || '',
|
||
assetNo: res.data.assetNo || '',
|
||
model: res.data.model || '',
|
||
specification: res.data.specification || '',
|
||
pumpSpeed: res.data.pumpSpeed || 0,
|
||
principalId: res.data.principalId,
|
||
pumpTimeout: res.data.pumpTimeout || 0,
|
||
maintenanceFlag: res.data.maintenanceFlag ?? 1,
|
||
ip: res.data.ip || '',
|
||
port: res.data.port || '',
|
||
speedCoefficient: res.data.speedCoefficient || 0,
|
||
serviceName: res.data.serviceName || '',
|
||
isAirPump: true, // 固定为false
|
||
configId: res.data.configId,
|
||
workingSpeed: res.data.workingSpeed || 0,
|
||
workingTime: res.data.workingTime || 0,
|
||
}
|
||
}
|
||
} catch (error: any) {
|
||
if (error.response?.status === 500) {
|
||
proxy.$modal.msgError('服务器内部错误,请检查后台服务')
|
||
} else {
|
||
proxy.$modal.msgError(`获取详情失败: ${error.response?.data?.msg || error.message}`)
|
||
}
|
||
return
|
||
}
|
||
}
|
||
|
||
state.isShowDialog = true
|
||
}
|
||
|
||
// 关闭弹窗
|
||
const closeDialog = () => {
|
||
state.isShowDialog = false
|
||
resetForm()
|
||
}
|
||
|
||
// 重置表单
|
||
const resetForm = () => {
|
||
state.ruleForm = {
|
||
id: undefined,
|
||
deviceNo: '',
|
||
assetNo: '',
|
||
model: '',
|
||
specification: '',
|
||
pumpSpeed: 0,
|
||
principalId: undefined,
|
||
pumpTimeout: 0,
|
||
maintenanceFlag: 1,
|
||
ip: '',
|
||
port: '',
|
||
speedCoefficient: 0,
|
||
serviceName: '',
|
||
isAirPump: false,
|
||
configId: undefined,
|
||
workingSpeed: 0,
|
||
workingTime: 0,
|
||
}
|
||
}
|
||
|
||
// 获取用户选项
|
||
const getUserOptions = async () => {
|
||
try {
|
||
const userPageInput = {
|
||
currentPage: 1,
|
||
pageSize: 1000,
|
||
filter: {
|
||
orgId: null,
|
||
}
|
||
} as PageInputUserGetPageInput
|
||
|
||
const res = await new UserApi().getPage(userPageInput)
|
||
if (res?.success) {
|
||
state.userOptions = res.data?.list ?? []
|
||
}
|
||
} catch (error) {
|
||
// 静默处理错误
|
||
}
|
||
}
|
||
|
||
// 获取泵速策略选项
|
||
const getConfigOptions = async () => {
|
||
state.configLoading = true
|
||
try {
|
||
const res = await new FeedingConfigApi().getList()
|
||
if (res?.success && res.data) {
|
||
state.configOptions = res.data
|
||
}
|
||
} catch (error) {
|
||
// 静默处理错误
|
||
} finally {
|
||
state.configLoading = false
|
||
}
|
||
}
|
||
|
||
// 获取设备型号选项
|
||
const getModelOptions = async () => {
|
||
try {
|
||
const res = await new DictApi().getList(['PUMPTYPE'])
|
||
if (res?.success && res.data) {
|
||
// 注意:API返回的key是小写的 pumptype
|
||
state.modelOptions = res.data['pumptype'] || []
|
||
}
|
||
} catch (error) {
|
||
// 静默处理错误
|
||
}
|
||
}
|
||
|
||
// 取消
|
||
const onCancel = () => {
|
||
closeDialog()
|
||
}
|
||
|
||
// 提交
|
||
const onSubmit = () => {
|
||
pumpFormRef.value.validate(async (valid: boolean) => {
|
||
if (!valid) return false
|
||
|
||
state.loading = true
|
||
try {
|
||
let res = {} as any
|
||
// 确保 isAirPump 为 false
|
||
const formData = { ...state.ruleForm, isAirPump: true }
|
||
|
||
if (formData.id) {
|
||
res = await new PumpApi().update(formData as any, { showSuccessMessage: true })
|
||
} else {
|
||
res = await new PumpApi().add(formData as any, { showSuccessMessage: true })
|
||
}
|
||
|
||
if (res?.success) {
|
||
closeDialog()
|
||
emit('refresh')
|
||
eventBus.emit('refreshAirPump' as keyof MittType<any>)
|
||
}
|
||
} catch (error: any) {
|
||
proxy.$modal.msgError('操作失败')
|
||
} finally {
|
||
state.loading = false
|
||
}
|
||
})
|
||
}
|
||
|
||
// 暴露变量
|
||
defineExpose({
|
||
openDialog,
|
||
closeDialog,
|
||
})
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
.form-section {
|
||
margin-bottom: 24px;
|
||
|
||
&:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
}
|
||
|
||
.section-title {
|
||
font-size: 16px;
|
||
font-weight: 600;
|
||
color: #303133;
|
||
margin-bottom: 16px;
|
||
padding-bottom: 8px;
|
||
border-bottom: 2px solid #f0f0f0;
|
||
position: relative;
|
||
|
||
&:before {
|
||
content: '';
|
||
position: absolute;
|
||
left: 0;
|
||
bottom: -2px;
|
||
width: 40px;
|
||
height: 2px;
|
||
background: #409eff;
|
||
}
|
||
}
|
||
|
||
:deep(.el-form-item) {
|
||
margin-bottom: 18px;
|
||
}
|
||
|
||
:deep(.el-switch__label) {
|
||
font-size: 13px;
|
||
}
|
||
</style>
|