fix:施工立项修复了一下,完成了新增项目和编辑项目的功能
This commit is contained in:
parent
b3a33196ec
commit
35d6478dc3
|
@ -0,0 +1,280 @@
|
|||
<template>
|
||||
<!-- 基本信息 -->
|
||||
<a-divider orientation="left">基本信息</a-divider>
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-form-item field="projectName" label="项目名称" required>
|
||||
<a-input v-model="model.projectName" placeholder="请输入项目名称" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item field="farmAddress" label="地址">
|
||||
<a-input v-model="model.farmAddress" placeholder="请输入地址" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col>
|
||||
<a-button size="mini" @click="onMapSelect">
|
||||
<template #icon><icon-location /></template>
|
||||
地图选点
|
||||
</a-button>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-form-item field="projectManagerId" label="项目经理" required>
|
||||
<a-select v-model="model.projectManagerId" placeholder="请选择项目经理" :loading="userLoading">
|
||||
<a-option v-for="user in userOptions" :key="user.value" :value="user.value">{{ user.label }}</a-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-form-item field="inspectionUnit" label="业主">
|
||||
<a-input v-model="model.inspectionUnit" placeholder="请输入业主单位" @input="(val:any) => (model.farmName = val)" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item field="inspectionContact" label="业主单位联系人">
|
||||
<a-input v-model="model.inspectionContact" placeholder="请输入联系人" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-form-item field="inspectionPhone" label="业主单位联系电话">
|
||||
<a-input v-model="model.inspectionPhone" placeholder="请输入联系电话" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-form-item field="client" label="委托单位">
|
||||
<a-input v-model="model.client" placeholder="请输入委托单位" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item field="clientContact" label="委托单位联系人">
|
||||
<a-input v-model="model.clientContact" placeholder="请输入联系人" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-form-item field="clientPhone" label="委托单位联系电话">
|
||||
<a-input v-model="model.clientPhone" placeholder="请输入联系电话" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-form-item field="projectOrigin" label="项目来源" :rules="[{ required: true, message: '请输入项目来源' }]">
|
||||
<a-input v-model="model.projectOrigin" placeholder="请输入项目来源" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-divider orientation="left">任务设置</a-divider>
|
||||
<div class="mb-2">
|
||||
<a-button type="dashed" size="small" @click="addTask">
|
||||
<template #icon><icon-plus /></template>
|
||||
新增任务
|
||||
</a-button>
|
||||
</div>
|
||||
<div v-if="!model.tasks || model.tasks.length === 0" class="text-gray-500 mb-2">暂无任务。</div>
|
||||
<a-space direction="vertical" fill>
|
||||
<a-card v-for="(task, tIndex) in model.tasks" :key="tIndex" size="small">
|
||||
<template #title>
|
||||
<div class="flex items-center justify-between">
|
||||
<span>任务 {{ tIndex + 1 }}</span>
|
||||
<a-space>
|
||||
<a-button size="mini" @click="addSubtask(tIndex)">新增子任务</a-button>
|
||||
<a-button size="mini" status="danger" @click="removeTask(tIndex)">删除</a-button>
|
||||
</a-space>
|
||||
</div>
|
||||
</template>
|
||||
<a-row :gutter="12">
|
||||
<a-col :span="8">
|
||||
<a-form-item :field="`tasks.${tIndex}.taskName`" label="任务名称" required>
|
||||
<a-input v-model="task.taskName" placeholder="请输入任务名称" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="6">
|
||||
<a-form-item :field="`tasks.${tIndex}.taskCode`" label="任务编号">
|
||||
<a-input v-model="task.taskCode" placeholder="编号" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="6">
|
||||
<a-form-item :field="`tasks.${tIndex}.mainUserId`" label="负责人">
|
||||
<a-select v-model="task.mainUserId" placeholder="选择负责人" :loading="userLoading">
|
||||
<a-option v-for="u in userOptions" :key="u.value" :value="u.value">{{ u.label }}</a-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="4">
|
||||
<a-form-item :field="`tasks.${tIndex}.scales`" label="工量">
|
||||
<a-input-number v-model="task.scales" :min="0" :max="9999" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="12">
|
||||
<a-col :span="8">
|
||||
<a-form-item :field="`tasks.${tIndex}.planStartDate`" label="计划开始">
|
||||
<a-date-picker v-model="task.planStartDate" style="width: 100%" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="8">
|
||||
<a-form-item :field="`tasks.${tIndex}.planEndDate`" label="计划结束">
|
||||
<a-date-picker v-model="task.planEndDate" style="width: 100%" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="8">
|
||||
<a-form-item :field="`tasks.${tIndex}.taskGroupId`" label="任务组">
|
||||
<a-input-number v-model="task.taskGroupId" :min="0" placeholder="可选" style="width: 100%" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<div v-if="task.children && task.children.length">
|
||||
<a-divider orientation="left">子任务</a-divider>
|
||||
<a-card v-for="(sub, sIndex) in task.children" :key="sIndex" size="small" class="mb-2">
|
||||
<template #title>
|
||||
<div class="flex items-center justify-between">
|
||||
<span>子任务 {{ tIndex + 1 }}-{{ sIndex + 1 }}</span>
|
||||
<a-button size="mini" status="danger" @click="removeSubtask(tIndex, sIndex)">删除</a-button>
|
||||
</div>
|
||||
</template>
|
||||
<a-row :gutter="12">
|
||||
<a-col :span="8">
|
||||
<a-form-item :field="`tasks.${tIndex}.children.${sIndex}.taskName`" label="任务名称" required>
|
||||
<a-input v-model="sub.taskName" placeholder="请输入任务名称" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="6">
|
||||
<a-form-item :field="`tasks.${tIndex}.children.${sIndex}.taskCode`" label="任务编号">
|
||||
<a-input v-model="sub.taskCode" placeholder="编号" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="6">
|
||||
<a-form-item :field="`tasks.${tIndex}.children.${sIndex}.mainUserId`" label="负责人">
|
||||
<a-select v-model="sub.mainUserId" placeholder="选择负责人" :loading="userLoading">
|
||||
<a-option v-for="u in userOptions" :key="u.value" :value="u.value">{{ u.label }}</a-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="4">
|
||||
<a-form-item :field="`tasks.${tIndex}.children.${sIndex}.scales`" label="工量">
|
||||
<a-input-number v-model="sub.scales" :min="0" :max="9999" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="12">
|
||||
<a-col :span="8">
|
||||
<a-form-item :field="`tasks.${tIndex}.children.${sIndex}.planStartDate`" label="计划开始">
|
||||
<a-date-picker v-model="sub.planStartDate" style="width: 100%" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="8">
|
||||
<a-form-item :field="`tasks.${tIndex}.children.${sIndex}.planEndDate`" label="计划结束">
|
||||
<a-date-picker v-model="sub.planEndDate" style="width: 100%" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="8">
|
||||
<a-form-item :field="`tasks.${tIndex}.children.${sIndex}.taskGroupId`" label="任务组">
|
||||
<a-input-number v-model="sub.taskGroupId" :min="0" placeholder="可选" style="width: 100%" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-card>
|
||||
</div>
|
||||
</a-card>
|
||||
</a-space>
|
||||
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-form-item field="status" label="项目状态">
|
||||
<a-select v-model="model.status" placeholder="请选择状态">
|
||||
<a-option v-for="option in statusOptions" :key="option.value" :value="option.value">{{ option.label }}</a-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item field="scale" label="项目规模">
|
||||
<a-input-number v-model="model.scale" placeholder="请输入项目规模" :min="0" :max="999" :step="1" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-form-item field="startDate" label="开始时间">
|
||||
<a-date-picker v-model="model.startDate" style="width: 100%" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item field="endDate" label="结束时间">
|
||||
<a-date-picker v-model="model.endDate" style="width: 100%" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-form-item field="turbineModel" label="风机型号">
|
||||
<a-input v-model="model.turbineModel" placeholder="请输入风机型号" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<template v-if="showTurbineGrid">
|
||||
<a-divider orientation="left">风场信息可视化</a-divider>
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="24">
|
||||
<a-form-item label="机组网格布局">
|
||||
<a-space direction="vertical" style="width: 100%">
|
||||
<TurbineGrid v-model="model.turbineList" />
|
||||
</a-space>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { toRefs } from 'vue'
|
||||
import TurbineGrid from '../TurbineGrid.vue'
|
||||
|
||||
const props = defineProps<{
|
||||
model: any
|
||||
userOptions: { label: string; value: string }[]
|
||||
userLoading: boolean
|
||||
statusOptions: { label: string; value: number | string }[]
|
||||
addTask: () => void
|
||||
removeTask: (index: number) => void
|
||||
addSubtask: (parentIndex: number) => void
|
||||
removeSubtask: (parentIndex: number, index: number) => void
|
||||
onMapSelect: () => void
|
||||
showTurbineGrid?: boolean
|
||||
}>()
|
||||
|
||||
// 保持对父级 props 的响应性,避免解构/复制导致的“卡加载/选项不更新”
|
||||
const {
|
||||
model,
|
||||
userOptions,
|
||||
userLoading,
|
||||
statusOptions,
|
||||
addTask,
|
||||
removeTask,
|
||||
addSubtask,
|
||||
removeSubtask,
|
||||
onMapSelect,
|
||||
showTurbineGrid,
|
||||
} = toRefs(props)
|
||||
</script>
|
||||
|
|
@ -72,263 +72,27 @@
|
|||
</template>
|
||||
</GiTable>
|
||||
|
||||
<!-- 新增/编辑项目弹窗 -->
|
||||
<!-- 新增项目弹窗(与编辑分离) -->
|
||||
<a-modal
|
||||
v-model:visible="addModalVisible" :title="modalTitle" :ok-button-props="{ loading: submitLoading }"
|
||||
width="800px" modal-class="project-form-modal" @cancel="resetForm" @ok="handleSubmit"
|
||||
width="800px" modal-class="project-form-modal" @cancel="handleCancelAdd" @ok="handleSubmit"
|
||||
>
|
||||
<a-form
|
||||
ref="formRef" :model="form" :rules="formRules" layout="vertical"
|
||||
:style="{ maxHeight: '70vh', overflow: 'auto', padding: '0 10px' }"
|
||||
>
|
||||
<!-- 基本信息 -->
|
||||
<a-divider orientation="left">基本信息</a-divider>
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-form-item field="projectName" label="项目名称" required>
|
||||
<a-input v-model="form.projectName" placeholder="请输入项目名称" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item field="farmAddress" label="地址">
|
||||
<a-input v-model="form.farmAddress" placeholder="请输入地址" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col>
|
||||
<a-button size="mini" @click="() => { Message.info(`待开发`) }">
|
||||
<template #icon><icon-location /></template>
|
||||
地图选点
|
||||
</a-button>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-form-item field="projectManagerId" label="项目经理" required>
|
||||
<a-select v-model="form.projectManagerId" placeholder="请选择项目经理" :loading="userLoading">
|
||||
<a-option v-for="user in userOptions" :key="user.value" :value="user.value">
|
||||
{{ user.label }}
|
||||
</a-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-form-item field="inspectionUnit" label="业主">
|
||||
<a-input v-model="form.inspectionUnit" placeholder="请输入业主单位" @input="(val) => (form.farmName = val)" />
|
||||
<!-- 风场名称同步业主 -->
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item field="inspectionContact" label="业主单位联系人">
|
||||
<a-input v-model="form.inspectionContact" placeholder="请输入联系人" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-form-item field="inspectionPhone" label="业主单位联系电话">
|
||||
<a-input v-model="form.inspectionPhone" placeholder="请输入联系电话" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-form-item field="client" label="委托单位">
|
||||
<a-input v-model="form.client" placeholder="请输入委托单位" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item field="clientContact" label="委托单位联系人">
|
||||
<a-input v-model="form.clientContact" placeholder="请输入联系人" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-form-item field="clientPhone" label="委托单位联系电话">
|
||||
<a-input v-model="form.clientPhone" placeholder="请输入联系电话" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-form-item field="projectOrigin" label="项目来源" :rules="[{ required: true, message: '请输入项目来源' }]">
|
||||
<a-input v-model="form.projectOrigin" placeholder="请输入项目来源" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-divider orientation="left">任务设置</a-divider>
|
||||
<div class="mb-2">
|
||||
<a-button type="dashed" size="small" @click="addTask">
|
||||
<template #icon><icon-plus /></template>
|
||||
新增任务
|
||||
</a-button>
|
||||
</div>
|
||||
<div v-if="form.tasks.length === 0" class="text-gray-500 mb-2">暂无任务,请点击“新增任务”。</div>
|
||||
<a-space direction="vertical" fill>
|
||||
<a-card v-for="(task, tIndex) in form.tasks" :key="tIndex" size="small">
|
||||
<template #title>
|
||||
<div class="flex items-center justify-between">
|
||||
<span>任务 {{ tIndex + 1 }}</span>
|
||||
<a-space>
|
||||
<a-button size="mini" @click="addSubtask(tIndex)">新增子任务</a-button>
|
||||
<a-button size="mini" status="danger" @click="removeTask(tIndex)">删除</a-button>
|
||||
</a-space>
|
||||
</div>
|
||||
</template>
|
||||
<a-row :gutter="12">
|
||||
<a-col :span="8">
|
||||
<a-form-item :field="`tasks.${tIndex}.taskName`" label="任务名称" required>
|
||||
<a-input v-model="task.taskName" placeholder="请输入任务名称" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="6">
|
||||
<a-form-item :field="`tasks.${tIndex}.taskCode`" label="任务编号">
|
||||
<a-input v-model="task.taskCode" placeholder="编号" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="6">
|
||||
<a-form-item :field="`tasks.${tIndex}.mainUserId`" label="负责人">
|
||||
<a-select v-model="task.mainUserId" placeholder="选择负责人" :loading="userLoading">
|
||||
<a-option v-for="u in userOptions" :key="u.value" :value="u.value">{{ u.label }}</a-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="4">
|
||||
<a-form-item :field="`tasks.${tIndex}.scales`" label="工量">
|
||||
<a-input-number v-model="task.scales" :min="0" :max="9999" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="12">
|
||||
<a-col :span="8">
|
||||
<a-form-item :field="`tasks.${tIndex}.planStartDate`" label="计划开始">
|
||||
<a-date-picker v-model="task.planStartDate" style="width: 100%" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="8">
|
||||
<a-form-item :field="`tasks.${tIndex}.planEndDate`" label="计划结束">
|
||||
<a-date-picker v-model="task.planEndDate" style="width: 100%" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="8">
|
||||
<a-form-item :field="`tasks.${tIndex}.taskGroupId`" label="任务组">
|
||||
<a-input-number v-model="task.taskGroupId" :min="0" placeholder="可选" style="width: 100%" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<!-- 子任务 -->
|
||||
<div v-if="task.children && task.children.length">
|
||||
<a-divider orientation="left">子任务</a-divider>
|
||||
<a-card
|
||||
v-for="(sub, sIndex) in task.children"
|
||||
:key="sIndex"
|
||||
size="small"
|
||||
class="mb-2"
|
||||
>
|
||||
<template #title>
|
||||
<div class="flex items-center justify-between">
|
||||
<span>子任务 {{ tIndex + 1 }}-{{ sIndex + 1 }}</span>
|
||||
<a-button size="mini" status="danger" @click="removeSubtask(tIndex, sIndex)">删除</a-button>
|
||||
</div>
|
||||
</template>
|
||||
<a-row :gutter="12">
|
||||
<a-col :span="8">
|
||||
<a-form-item :field="`tasks.${tIndex}.children.${sIndex}.taskName`" label="任务名称" required>
|
||||
<a-input v-model="sub.taskName" placeholder="请输入任务名称" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="6">
|
||||
<a-form-item :field="`tasks.${tIndex}.children.${sIndex}.taskCode`" label="任务编号">
|
||||
<a-input v-model="sub.taskCode" placeholder="编号" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="6">
|
||||
<a-form-item :field="`tasks.${tIndex}.children.${sIndex}.mainUserId`" label="负责人">
|
||||
<a-select v-model="sub.mainUserId" placeholder="选择负责人" :loading="userLoading">
|
||||
<a-option v-for="u in userOptions" :key="u.value" :value="u.value">{{ u.label }}</a-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="4">
|
||||
<a-form-item :field="`tasks.${tIndex}.children.${sIndex}.scales`" label="工量">
|
||||
<a-input-number v-model="sub.scales" :min="0" :max="9999" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="12">
|
||||
<a-col :span="8">
|
||||
<a-form-item :field="`tasks.${tIndex}.children.${sIndex}.planStartDate`" label="计划开始">
|
||||
<a-date-picker v-model="sub.planStartDate" style="width: 100%" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="8">
|
||||
<a-form-item :field="`tasks.${tIndex}.children.${sIndex}.planEndDate`" label="计划结束">
|
||||
<a-date-picker v-model="sub.planEndDate" style="width: 100%" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="8">
|
||||
<a-form-item :field="`tasks.${tIndex}.children.${sIndex}.taskGroupId`" label="任务组">
|
||||
<a-input-number v-model="sub.taskGroupId" :min="0" placeholder="可选" style="width: 100%" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-card>
|
||||
</div>
|
||||
</a-card>
|
||||
</a-space>
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-form-item field="status" label="项目状态">
|
||||
<a-select v-model="form.status" placeholder="请选择状态">
|
||||
<a-option v-for="option in PROJECT_STATUS_OPTIONS" :key="option.value" :value="option.value">
|
||||
{{ option.label }}
|
||||
</a-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item field="scale" label="项目规模">
|
||||
<a-input-number v-model="form.scale" placeholder="请输入项目规模" :min="0" :max="999" :step="1" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-form-item field="startDate" label="开始时间">
|
||||
<a-date-picker v-model="form.startDate" style="width: 100%" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item field="endDate" label="结束时间">
|
||||
<a-date-picker v-model="form.endDate" style="width: 100%" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-form-item field="turbineModel" label="风机型号">
|
||||
<a-input v-model="form.turbineModel" placeholder="请输入风机型号" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<!-- 风场信息 -->
|
||||
<a-divider orientation="left">风场信息可视化</a-divider>
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="24">
|
||||
<a-form-item label="机组网格布局">
|
||||
<a-space direction="vertical" style="width: 100%">
|
||||
<TurbineGrid v-model:="form.turbineList"></TurbineGrid>
|
||||
</a-space>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-divider orientation="middle">地图</a-divider>
|
||||
<ProjectFormFields
|
||||
:model="form"
|
||||
:user-options="userOptions"
|
||||
:user-loading="userLoading"
|
||||
:status-options="PROJECT_STATUS_OPTIONS"
|
||||
:add-task="addTask"
|
||||
:remove-task="removeTask"
|
||||
:add-subtask="addSubtask"
|
||||
:remove-subtask="removeSubtask"
|
||||
:on-map-select="() => { Message.info('待开发') }"
|
||||
:show-turbine-grid="true"
|
||||
/>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
|
||||
|
@ -339,9 +103,10 @@
|
|||
:ok-button-props="{ loading: submitLoading }"
|
||||
width="800px"
|
||||
modal-class="project-form-modal"
|
||||
@cancel="() => { editModalVisible.value = false }"
|
||||
@cancel="handleCancelEdit"
|
||||
@ok="handleEditSubmit"
|
||||
>
|
||||
<a-spin :loading="editDetailLoading">
|
||||
<a-form
|
||||
ref="editFormRef"
|
||||
:model="editForm"
|
||||
|
@ -349,229 +114,21 @@
|
|||
layout="vertical"
|
||||
:style="{ maxHeight: '70vh', overflow: 'auto', padding: '0 10px' }"
|
||||
>
|
||||
<a-divider orientation="left">基本信息</a-divider>
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-form-item field="projectName" label="项目名称" required>
|
||||
<a-input v-model="editForm.projectName" placeholder="请输入项目名称" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item field="farmAddress" label="地址">
|
||||
<a-input v-model="editForm.farmAddress" placeholder="请输入地址" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<ProjectFormFields
|
||||
:model="editForm"
|
||||
:user-options="userOptions"
|
||||
:user-loading="userLoading"
|
||||
:status-options="PROJECT_STATUS_OPTIONS"
|
||||
:add-task="addEditTask"
|
||||
:remove-task="removeEditTask"
|
||||
:add-subtask="addEditSubtask"
|
||||
:remove-subtask="removeEditSubtask"
|
||||
:on-map-select="() => {}"
|
||||
:show-turbine-grid="false"
|
||||
/>
|
||||
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-form-item field="projectManagerId" label="项目经理" required>
|
||||
<a-select v-model="editForm.projectManagerId" placeholder="请选择项目经理" :loading="userLoading">
|
||||
<a-option v-for="user in userOptions" :key="user.value" :value="user.value">
|
||||
{{ user.label }}
|
||||
</a-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-form-item field="inspectionUnit" label="业主">
|
||||
<a-input v-model="editForm.inspectionUnit" placeholder="请输入业主单位" @input="(val) => (editForm.farmName = val)" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item field="inspectionContact" label="业主单位联系人">
|
||||
<a-input v-model="editForm.inspectionContact" placeholder="请输入联系人" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-form-item field="inspectionPhone" label="业主单位联系电话">
|
||||
<a-input v-model="editForm.inspectionPhone" placeholder="请输入联系电话" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-form-item field="client" label="委托单位">
|
||||
<a-input v-model="editForm.client" placeholder="请输入委托单位" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item field="clientContact" label="委托单位联系人">
|
||||
<a-input v-model="editForm.clientContact" placeholder="请输入联系人" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-form-item field="clientPhone" label="委托单位联系电话">
|
||||
<a-input v-model="editForm.clientPhone" placeholder="请输入联系电话" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-form-item field="projectOrigin" label="项目来源" :rules="[{ required: true, message: '请输入项目来源' }]">
|
||||
<a-input v-model="editForm.projectOrigin" placeholder="请输入项目来源" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-divider orientation="left">任务设置</a-divider>
|
||||
<div class="mb-2">
|
||||
<a-button type="dashed" size="small" @click="addEditTask">
|
||||
<template #icon><icon-plus /></template>
|
||||
新增任务
|
||||
</a-button>
|
||||
</div>
|
||||
<div v-if="editForm.tasks.length === 0" class="text-gray-500 mb-2">暂无任务。</div>
|
||||
<a-space direction="vertical" fill>
|
||||
<a-card v-for="(task, tIndex) in editForm.tasks" :key="tIndex" size="small">
|
||||
<template #title>
|
||||
<div class="flex items-center justify-between">
|
||||
<span>任务 {{ tIndex + 1 }}</span>
|
||||
<a-space>
|
||||
<a-button size="mini" @click="addEditSubtask(tIndex)">新增子任务</a-button>
|
||||
<a-button size="mini" status="danger" @click="removeEditTask(tIndex)">删除</a-button>
|
||||
</a-space>
|
||||
</div>
|
||||
</template>
|
||||
<a-row :gutter="12">
|
||||
<a-col :span="8">
|
||||
<a-form-item :field="`tasks.${tIndex}.taskName`" label="任务名称" required>
|
||||
<a-input v-model="task.taskName" placeholder="请输入任务名称" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="6">
|
||||
<a-form-item :field="`tasks.${tIndex}.taskCode`" label="任务编号">
|
||||
<a-input v-model="task.taskCode" placeholder="编号" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="6">
|
||||
<a-form-item :field="`tasks.${tIndex}.mainUserId`" label="负责人">
|
||||
<a-select v-model="task.mainUserId" placeholder="选择负责人" :loading="userLoading">
|
||||
<a-option v-for="u in userOptions" :key="u.value" :value="u.value">{{ u.label }}</a-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="4">
|
||||
<a-form-item :field="`tasks.${tIndex}.scales`" label="工量">
|
||||
<a-input-number v-model="task.scales" :min="0" :max="9999" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="12">
|
||||
<a-col :span="8">
|
||||
<a-form-item :field="`tasks.${tIndex}.planStartDate`" label="计划开始">
|
||||
<a-date-picker v-model="task.planStartDate" style="width: 100%" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="8">
|
||||
<a-form-item :field="`tasks.${tIndex}.planEndDate`" label="计划结束">
|
||||
<a-date-picker v-model="task.planEndDate" style="width: 100%" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="8">
|
||||
<a-form-item :field="`tasks.${tIndex}.taskGroupId`" label="任务组">
|
||||
<a-input-number v-model="task.taskGroupId" :min="0" placeholder="可选" style="width: 100%" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<!-- 子任务 -->
|
||||
<div v-if="task.children && task.children.length">
|
||||
<a-divider orientation="left">子任务</a-divider>
|
||||
<a-card v-for="(sub, sIndex) in task.children" :key="sIndex" size="small" class="mb-2">
|
||||
<template #title>
|
||||
<div class="flex items-center justify-between">
|
||||
<span>子任务 {{ tIndex + 1 }}-{{ sIndex + 1 }}</span>
|
||||
<a-button size="mini" status="danger" @click="removeEditSubtask(tIndex, sIndex)">删除</a-button>
|
||||
</div>
|
||||
</template>
|
||||
<a-row :gutter="12">
|
||||
<a-col :span="8">
|
||||
<a-form-item :field="`tasks.${tIndex}.children.${sIndex}.taskName`" label="任务名称" required>
|
||||
<a-input v-model="sub.taskName" placeholder="请输入任务名称" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="6">
|
||||
<a-form-item :field="`tasks.${tIndex}.children.${sIndex}.taskCode`" label="任务编号">
|
||||
<a-input v-model="sub.taskCode" placeholder="编号" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="6">
|
||||
<a-form-item :field="`tasks.${tIndex}.children.${sIndex}.mainUserId`" label="负责人">
|
||||
<a-select v-model="sub.mainUserId" placeholder="选择负责人" :loading="userLoading">
|
||||
<a-option v-for="u in userOptions" :key="u.value" :value="u.value">{{ u.label }}</a-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="4">
|
||||
<a-form-item :field="`tasks.${tIndex}.children.${sIndex}.scales`" label="工量">
|
||||
<a-input-number v-model="sub.scales" :min="0" :max="9999" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="12">
|
||||
<a-col :span="8">
|
||||
<a-form-item :field="`tasks.${tIndex}.children.${sIndex}.planStartDate`" label="计划开始">
|
||||
<a-date-picker v-model="sub.planStartDate" style="width: 100%" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="8">
|
||||
<a-form-item :field="`tasks.${tIndex}.children.${sIndex}.planEndDate`" label="计划结束">
|
||||
<a-date-picker v-model="sub.planEndDate" style="width: 100%" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="8">
|
||||
<a-form-item :field="`tasks.${tIndex}.children.${sIndex}.taskGroupId`" label="任务组">
|
||||
<a-input-number v-model="sub.taskGroupId" :min="0" placeholder="可选" style="width: 100%" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-card>
|
||||
</div>
|
||||
</a-card>
|
||||
</a-space>
|
||||
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-form-item field="status" label="项目状态">
|
||||
<a-select v-model="editForm.status" placeholder="请选择状态">
|
||||
<a-option v-for="option in PROJECT_STATUS_OPTIONS" :key="option.value" :value="option.value">
|
||||
{{ option.label }}
|
||||
</a-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item field="scale" label="项目规模">
|
||||
<a-input-number v-model="editForm.scale" placeholder="请输入项目规模" :min="0" :max="999" :step="1" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-form-item field="startDate" label="开始时间">
|
||||
<a-date-picker v-model="editForm.startDate" style="width: 100%" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item field="endDate" label="结束时间">
|
||||
<a-date-picker v-model="editForm.endDate" style="width: 100%" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</a-spin>
|
||||
</a-modal>
|
||||
|
||||
|
||||
|
@ -651,8 +208,11 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import ProjectFormFields from './components/ProjectFormFields.vue'
|
||||
|
||||
const editModalVisible = ref(false)
|
||||
const editFormRef = ref()
|
||||
const editDetailLoading = ref(false)
|
||||
|
||||
// 编辑表单
|
||||
const editForm = reactive({
|
||||
|
@ -702,7 +262,6 @@ import { computed, onMounted, reactive, ref } from 'vue'
|
|||
import { useRouter } from 'vue-router'
|
||||
import { Message, Modal } from '@arco-design/web-vue'
|
||||
import type { TableColumnData } from '@arco-design/web-vue'
|
||||
import TurbineGrid from './TurbineGrid.vue'
|
||||
import { addProject, deleteProject, exportProject, importProject, listProject, updateProject, getProjectDetail } from '@/apis/project'
|
||||
import { isMobile } from '@/utils'
|
||||
import http from '@/utils/http'
|
||||
|
@ -1046,6 +605,16 @@ const fetchData = async () => {
|
|||
}
|
||||
} else {
|
||||
Message.error(res.msg || '获取数据失败')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取项目列表失败:', error)
|
||||
Message.error('获取数据失败')
|
||||
dataList.value = []
|
||||
pagination.total = 0
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const handleEditSubmit = async () => {
|
||||
submitLoading.value = true
|
||||
|
@ -1134,18 +703,6 @@ const handleEditSubmit = async () => {
|
|||
}
|
||||
}
|
||||
|
||||
dataList.value = []
|
||||
pagination.total = 0
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取项目列表失败:', error)
|
||||
Message.error('获取数据失败')
|
||||
dataList.value = []
|
||||
pagination.total = 0
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const search = () => {
|
||||
pagination.current = 1
|
||||
|
@ -1210,7 +767,29 @@ const resetForm = () => {
|
|||
|
||||
const openAddModal = () => {
|
||||
resetForm()
|
||||
editModalVisible.value = true
|
||||
addModalVisible.value = true
|
||||
}
|
||||
// 编辑任务增删改
|
||||
const addEditTask = () => {
|
||||
;(editForm.tasks as any[]).push({ taskName: '', taskCode: '', mainUserId: undefined, planStartDate: '', planEndDate: '', scales: undefined, taskGroupId: undefined, children: [] })
|
||||
}
|
||||
const removeEditTask = (index: number) => {
|
||||
;(editForm.tasks as any[]).splice(index, 1)
|
||||
}
|
||||
const addEditSubtask = (parentIndex: number) => {
|
||||
const list = (editForm.tasks as any[])
|
||||
if (!list[parentIndex].children) list[parentIndex].children = []
|
||||
list[parentIndex].children!.push({ taskName: '', taskCode: '', mainUserId: undefined, planStartDate: '', planEndDate: '', scales: undefined, taskGroupId: undefined })
|
||||
}
|
||||
const removeEditSubtask = (parentIndex: number, index: number) => {
|
||||
const list = (editForm.tasks as any[])
|
||||
list[parentIndex].children!.splice(index, 1)
|
||||
}
|
||||
|
||||
|
||||
const handleCancelAdd = () => {
|
||||
addModalVisible.value = false
|
||||
resetForm()
|
||||
}
|
||||
// 任务增删改(仅在新增/编辑弹窗内部使用)
|
||||
const addTask = () => {
|
||||
|
@ -1234,6 +813,10 @@ const openEditModal = async (record: T.ProjectResp) => {
|
|||
isEdit.value = true
|
||||
currentId.value = record.id || record.projectId || null
|
||||
|
||||
// 先打开弹窗并显示加载态
|
||||
editModalVisible.value = true
|
||||
editDetailLoading.value = true
|
||||
|
||||
// 重置编辑表单
|
||||
Object.assign(editForm, {
|
||||
projectId: '', projectName: '', projectManagerId: '', client: '', clientContact: '', clientPhone: '',
|
||||
|
@ -1242,6 +825,18 @@ const openEditModal = async (record: T.ProjectResp) => {
|
|||
qualityOfficerId: '', auditorId: '', tasks: [], turbineList: [],
|
||||
})
|
||||
|
||||
// 先用列表记录进行快速预填,保证弹窗“秒开”可编辑
|
||||
if (record && typeof record === 'object') {
|
||||
Object.keys(editForm).forEach((key) => {
|
||||
if ((record as any)[key] !== undefined) {
|
||||
// @ts-expect-error 动态赋值
|
||||
editForm[key] = (record as any)[key]
|
||||
}
|
||||
})
|
||||
}
|
||||
// 预填完成后立即关闭整体加载,避免空任务时长时间转圈
|
||||
editDetailLoading.value = false
|
||||
|
||||
try {
|
||||
if (currentId.value) {
|
||||
const res = await getProjectDetail(currentId.value as any)
|
||||
|
@ -1281,9 +876,9 @@ const openEditModal = async (record: T.ProjectResp) => {
|
|||
const tasksSource: any[] = Array.isArray(detail.tasks)
|
||||
? detail.tasks
|
||||
: (Array.isArray((detail as any).taskList) ? (detail as any).taskList : [])
|
||||
if (Array.isArray(tasksSource) && tasksSource.length) {
|
||||
;(editForm.tasks as any[]) = tasksSource.map(mapTask)
|
||||
}
|
||||
|
||||
// 任务为空时也要保证是数组,避免渲染卡住
|
||||
;(editForm.tasks as any[]) = Array.isArray(tasksSource) ? tasksSource.map(mapTask) : []
|
||||
|
||||
// projectId 保证存在
|
||||
editForm.projectId = (detail.projectId ?? currentId.value ?? record.projectId ?? '').toString()
|
||||
|
@ -1297,10 +892,16 @@ const openEditModal = async (record: T.ProjectResp) => {
|
|||
editForm[key] = (record as any)[key]
|
||||
}
|
||||
})
|
||||
} finally {
|
||||
editDetailLoading.value = false
|
||||
}
|
||||
|
||||
// 打开编辑弹窗(与新增分离)
|
||||
editModalVisible.value = true
|
||||
// 取消编辑
|
||||
|
||||
}
|
||||
|
||||
const handleCancelEdit = () => {
|
||||
editModalVisible.value = false
|
||||
}
|
||||
|
||||
// 添加表单验证规则
|
||||
|
|
Loading…
Reference in New Issue