Industrial-image-management.../src/views/project/kanban/components/TaskModal.vue

262 lines
7.2 KiB
Vue

<!--
任务新增/编辑弹窗组件
-->
<template>
<a-modal
v-model:visible="visible"
:title="isEdit ? '编辑任务' : '新增任务'"
width="800px"
@before-ok="handleSubmit"
@cancel="handleCancel"
>
<a-form ref="formRef" :model="form" :rules="rules" layout="vertical">
<a-row :gutter="16">
<a-col :span="12">
<a-form-item field="taskName" label="任务名称" required>
<a-input v-model="form.taskName" placeholder="请输入任务名称" />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item field="taskCode" label="任务编码" required>
<a-input v-model="form.taskCode" placeholder="请输入任务编码" />
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="16">
<a-col :span="12">
<a-form-item field="responsiblePerson" label="负责人" required>
<a-input v-model="form.responsiblePerson" placeholder="请输入负责人" />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item field="status" label="任务状态" required>
<a-select v-model="form.status" placeholder="请选择状态">
<a-option value="planning">计划中</a-option>
<a-option value="inProgress">正在做</a-option>
<a-option value="review">待复核</a-option>
<a-option value="completed">已完成</a-option>
<a-option value="other">其他</a-option>
</a-select>
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="16">
<a-col :span="12">
<a-form-item field="progress" label="任务进度">
<a-input-number
v-model="form.progress"
placeholder="请输入进度"
:min="0"
:max="100"
:precision="0"
style="width: 100%"
>
<template #suffix>%</template>
</a-input-number>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item field="plannedHours" label="计划工时">
<a-input-number
v-model="form.plannedHours"
placeholder="请输入计划工时"
:min="0"
:precision="1"
style="width: 100%"
>
<template #suffix>小时</template>
</a-input-number>
</a-form-item>
</a-col>
</a-row>
<a-form-item field="taskPeriod" label="任务周期">
<a-range-picker
v-model="form.taskPeriod"
style="width: 100%"
format="YYYY-MM-DD"
/>
</a-form-item>
<a-form-item field="participants" label="参与人员">
<a-select
v-model="form.participants"
placeholder="请选择参与人员"
multiple
allow-create
style="width: 100%"
>
<a-option v-for="user in userOptions" :key="user" :value="user">
{{ user }}
</a-option>
</a-select>
</a-form-item>
<a-form-item field="description" label="任务描述">
<a-textarea
v-model="form.description"
placeholder="请输入任务描述"
:rows="4"
/>
</a-form-item>
</a-form>
</a-modal>
</template>
<script setup lang="ts">
import { ref, reactive, watch, nextTick } from 'vue'
import { Message, type FormInstance } from '@arco-design/web-vue'
import { addTask, updateTask, getTask } from '@/apis/project/task'
import type { TaskResp } from '@/apis/project/type'
interface Props {
visible: boolean
projectId?: string
initialStatus?: string
taskData?: TaskResp | null
}
interface Emits {
(e: 'update:visible', value: boolean): void
(e: 'success'): void
}
const props = withDefaults(defineProps<Props>(), {
visible: false,
initialStatus: 'planning',
taskData: null
})
const emit = defineEmits<Emits>()
const visible = ref(props.visible)
const formRef = ref<FormInstance>()
const isEdit = ref(false)
// 表单数据
const form = reactive({
taskName: '',
taskCode: '',
responsiblePerson: '',
participants: [] as string[],
taskPeriod: [] as string[],
status: 'planning',
progress: 0,
plannedHours: 0,
description: '',
projectId: 0,
groupId: undefined as number | undefined,
superior: undefined as number | undefined
})
// 表单验证规则
const rules = {
taskName: [{ required: true, message: '请输入任务名称' }],
taskCode: [{ required: true, message: '请输入任务编码' }],
responsiblePerson: [{ required: true, message: '请输入负责人' }],
status: [{ required: true, message: '请选择任务状态' }]
}
// 用户选项(模拟数据)
const userOptions = ref([
'张三', '李四', '王五', '赵六', '钱七', '孙八', '周九', '吴十'
])
// 监听visible变化
watch(() => props.visible, (newVal) => {
visible.value = newVal
if (newVal) {
nextTick(() => {
initForm()
})
}
})
watch(visible, (newVal) => {
emit('update:visible', newVal)
})
// 初始化表单
const initForm = () => {
if (props.taskData) {
// 编辑模式
isEdit.value = true
form.taskName = props.taskData.taskName
form.taskCode = props.taskData.taskCode
form.responsiblePerson = props.taskData.responsiblePerson
form.participants = props.taskData.participants || []
form.taskPeriod = props.taskData.taskPeriod || []
form.status = props.taskData.status
form.progress = props.taskData.progress || 0
form.plannedHours = props.taskData.plannedHours || 0
form.description = props.taskData.description || ''
form.projectId = props.taskData.projectId
form.groupId = props.taskData.groupId
form.superior = props.taskData.superior
} else {
// 新增模式
isEdit.value = false
resetForm()
form.status = props.initialStatus || 'planning'
form.projectId = Number(props.projectId) || 0
}
}
// 重置表单
const resetForm = () => {
form.taskName = ''
form.taskCode = ''
form.responsiblePerson = ''
form.participants = []
form.taskPeriod = []
form.status = 'planning'
form.progress = 0
form.plannedHours = 0
form.description = ''
form.projectId = 0
form.groupId = undefined
form.superior = undefined
}
// 提交表单
const handleSubmit = async () => {
try {
const isValid = await formRef.value?.validate()
if (!isValid) {
return false
}
const formData = {
...form,
taskPeriod: form.taskPeriod.length === 2 ? form.taskPeriod as [string, string] : undefined
}
if (isEdit.value && props.taskData) {
await updateTask(formData, props.taskData.id)
Message.success('任务更新成功')
} else {
await addTask(formData)
Message.success('任务创建成功')
}
emit('success')
return true
} catch (error) {
console.error('提交任务失败:', error)
Message.error(isEdit.value ? '更新任务失败' : '创建任务失败')
return false
}
}
// 取消操作
const handleCancel = () => {
formRef.value?.clearValidate()
resetForm()
}
</script>
<style scoped lang="scss">
// 弹窗样式可以根据需要添加
</style>