feat: 完成需求工单管理模块(全栈开发)
后端: - 创建 Requirement 实体类(映射 requirement 表) - 创建 RequirementMapper 接口(含自定义查询) - 创建 RequirementService 业务逻辑层 - 分页查询(支持多条件筛选) - 新增/更新/删除需求 - 更新需求状态和进度 - 自动设置默认租户ID - 创建 RequirementController 控制器 - RESTful API 设计 - 状态管理和进度跟踪 前端: - 创建 requirement.js API 文件(完整的 CRUD 接口) - 创建 requirement.vue 管理页面 - 多条件搜索(需求名称、项目、客户、状态) - 表格展示(含状态标签、优先级标签、进度条) - 新增/编辑表单(支持工时、日期、应收款管理) - 状态更新对话框 - 进度更新对话框(滑块组件) - 项目和客户下拉选择 - 添加路由配置(/project/requirement)
This commit is contained in:
parent
1a47943b10
commit
9c00696baf
76
fund-admin/src/api/requirement.js
Normal file
76
fund-admin/src/api/requirement.js
Normal file
@ -0,0 +1,76 @@
|
||||
import request from '../utils/request'
|
||||
|
||||
/**
|
||||
* 获取需求工单列表
|
||||
*/
|
||||
export const getRequirementList = (params) => {
|
||||
return request({
|
||||
url: '/proj/api/v1/requirement/list',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取需求工单详情
|
||||
*/
|
||||
export const getRequirementById = (requirementId) => {
|
||||
return request({
|
||||
url: `/proj/api/v1/requirement/${requirementId}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建需求工单
|
||||
*/
|
||||
export const createRequirement = (data) => {
|
||||
return request({
|
||||
url: '/proj/api/v1/requirement',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新需求工单
|
||||
*/
|
||||
export const updateRequirement = (requirementId, data) => {
|
||||
return request({
|
||||
url: `/proj/api/v1/requirement/${requirementId}`,
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除需求工单
|
||||
*/
|
||||
export const deleteRequirement = (requirementId) => {
|
||||
return request({
|
||||
url: `/proj/api/v1/requirement/${requirementId}`,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新需求状态
|
||||
*/
|
||||
export const updateRequirementStatus = (requirementId, status) => {
|
||||
return request({
|
||||
url: `/proj/api/v1/requirement/${requirementId}/status`,
|
||||
method: 'put',
|
||||
params: { status }
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新需求进度
|
||||
*/
|
||||
export const updateRequirementProgress = (requirementId, progress) => {
|
||||
return request({
|
||||
url: `/proj/api/v1/requirement/${requirementId}/progress`,
|
||||
method: 'put',
|
||||
params: { progress }
|
||||
})
|
||||
}
|
||||
@ -86,6 +86,12 @@ const routes = [
|
||||
name: 'Contract',
|
||||
component: () => import('../views/project/contract.vue'),
|
||||
meta: { title: '合同管理' }
|
||||
},
|
||||
{
|
||||
path: 'requirement',
|
||||
name: 'Requirement',
|
||||
component: () => import('../views/project/requirement.vue'),
|
||||
meta: { title: '需求工单' }
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
641
fund-admin/src/views/project/requirement.vue
Normal file
641
fund-admin/src/views/project/requirement.vue
Normal file
@ -0,0 +1,641 @@
|
||||
<template>
|
||||
<div class="requirement-container">
|
||||
<el-card>
|
||||
<!-- 搜索栏 -->
|
||||
<el-form :inline="true" :model="searchForm">
|
||||
<el-form-item label="需求名称">
|
||||
<el-input v-model="searchForm.requirementName" placeholder="请输入需求名称" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="项目">
|
||||
<el-select v-model="searchForm.projectId" placeholder="请选择项目" clearable>
|
||||
<el-option
|
||||
v-for="project in projectOptions"
|
||||
:key="project.projectId"
|
||||
:label="project.projectName"
|
||||
:value="project.projectId"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="客户">
|
||||
<el-select v-model="searchForm.customerId" placeholder="请选择客户" clearable>
|
||||
<el-option
|
||||
v-for="customer in customerOptions"
|
||||
:key="customer.customerId"
|
||||
:label="customer.customerName"
|
||||
:value="customer.customerId"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态">
|
||||
<el-select v-model="searchForm.status" placeholder="请选择状态" clearable>
|
||||
<el-option label="待开发" value="pending" />
|
||||
<el-option label="开发中" value="developing" />
|
||||
<el-option label="已交付" value="delivered" />
|
||||
<el-option label="已完成" value="completed" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleSearch">搜索</el-button>
|
||||
<el-button @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<!-- 操作栏 -->
|
||||
<el-row style="margin-bottom: 15px;">
|
||||
<el-button type="primary" @click="handleAdd">新增需求</el-button>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table :data="tableData" border v-loading="loading">
|
||||
<el-table-column prop="requirementCode" label="需求编号" width="150" />
|
||||
<el-table-column prop="requirementName" label="需求名称" width="200" />
|
||||
<el-table-column prop="projectId" label="项目" width="150">
|
||||
<template #default="{ row }">
|
||||
{{ getProjectName(row.projectId) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="customerName" label="客户" width="150">
|
||||
<template #default="{ row }">
|
||||
{{ getCustomerName(row.customerId) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="priority" label="优先级" width="100">
|
||||
<template #default="{ row }">
|
||||
<el-tag v-if="row.priority === 'high'" type="danger">高</el-tag>
|
||||
<el-tag v-else-if="row.priority === 'normal'" type="warning">中</el-tag>
|
||||
<el-tag v-else type="info">低</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="status" label="状态" width="100">
|
||||
<template #default="{ row }">
|
||||
<el-tag v-if="row.status === 'pending'" type="info">待开发</el-tag>
|
||||
<el-tag v-else-if="row.status === 'developing'" type="primary">开发中</el-tag>
|
||||
<el-tag v-else-if="row.status === 'delivered'" type="warning">已交付</el-tag>
|
||||
<el-tag v-else-if="row.status === 'completed'" type="success">已完成</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="progress" label="进度" width="120">
|
||||
<template #default="{ row }">
|
||||
<el-progress :percentage="row.progress" :color="getProgressColor(row.progress)" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="estimatedHours" label="预估工时(h)" width="120" />
|
||||
<el-table-column prop="actualHours" label="实际工时(h)" width="120" />
|
||||
<el-table-column prop="receivableAmount" label="应收款" width="120">
|
||||
<template #default="{ row }">
|
||||
{{ row.receivableAmount ? '¥' + row.receivableAmount : '-' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createdTime" label="创建时间" width="180" />
|
||||
<el-table-column label="操作" width="280" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button type="primary" size="small" @click="handleEdit(row)">编辑</el-button>
|
||||
<el-button type="info" size="small" @click="handleUpdateStatus(row)">更新状态</el-button>
|
||||
<el-button type="warning" size="small" @click="handleUpdateProgress(row)">更新进度</el-button>
|
||||
<el-button type="danger" size="small" @click="handleDelete(row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<el-pagination
|
||||
v-model:current-page="page.current"
|
||||
v-model:page-size="page.size"
|
||||
:total="page.total"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
@size-change="fetchData"
|
||||
@current-change="fetchData"
|
||||
style="margin-top: 20px; justify-content: flex-end;"
|
||||
/>
|
||||
</el-card>
|
||||
|
||||
<!-- 新增/编辑对话框 -->
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:title="form.requirementId ? '编辑需求' : '新增需求'"
|
||||
width="800px"
|
||||
>
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="120px">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="需求编号" prop="requirementCode">
|
||||
<el-input v-model="form.requirementCode" placeholder="请输入需求编号" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="需求名称" prop="requirementName">
|
||||
<el-input v-model="form.requirementName" placeholder="请输入需求名称" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="项目" prop="projectId">
|
||||
<el-select v-model="form.projectId" placeholder="请选择项目" style="width: 100%;">
|
||||
<el-option
|
||||
v-for="project in projectOptions"
|
||||
:key="project.projectId"
|
||||
:label="project.projectName"
|
||||
:value="project.projectId"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="客户" prop="customerId">
|
||||
<el-select v-model="form.customerId" placeholder="请选择客户" style="width: 100%;">
|
||||
<el-option
|
||||
v-for="customer in customerOptions"
|
||||
:key="customer.customerId"
|
||||
:label="customer.customerName"
|
||||
:value="customer.customerId"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="优先级" prop="priority">
|
||||
<el-select v-model="form.priority" placeholder="请选择优先级" style="width: 100%;">
|
||||
<el-option label="高" value="high" />
|
||||
<el-option label="中" value="normal" />
|
||||
<el-option label="低" value="low" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-select v-model="form.status" placeholder="请选择状态" style="width: 100%;">
|
||||
<el-option label="待开发" value="pending" />
|
||||
<el-option label="开发中" value="developing" />
|
||||
<el-option label="已交付" value="delivered" />
|
||||
<el-option label="已完成" value="completed" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-form-item label="需求描述" prop="description">
|
||||
<el-input
|
||||
v-model="form.description"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入需求描述"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="预估工时(h)" prop="estimatedHours">
|
||||
<el-input-number v-model="form.estimatedHours" :min="0" :precision="2" style="width: 100%;" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="实际工时(h)" prop="actualHours">
|
||||
<el-input-number v-model="form.actualHours" :min="0" :precision="2" style="width: 100%;" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="计划开始日期" prop="plannedStart">
|
||||
<el-date-picker
|
||||
v-model="form.plannedStart"
|
||||
type="date"
|
||||
placeholder="选择日期"
|
||||
style="width: 100%;"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="计划结束日期" prop="plannedEnd">
|
||||
<el-date-picker
|
||||
v-model="form.plannedEnd"
|
||||
type="date"
|
||||
placeholder="选择日期"
|
||||
style="width: 100%;"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="实际开始日期" prop="actualStart">
|
||||
<el-date-picker
|
||||
v-model="form.actualStart"
|
||||
type="date"
|
||||
placeholder="选择日期"
|
||||
style="width: 100%;"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="实际结束日期" prop="actualEnd">
|
||||
<el-date-picker
|
||||
v-model="form.actualEnd"
|
||||
type="date"
|
||||
placeholder="选择日期"
|
||||
style="width: 100%;"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="应收款金额" prop="receivableAmount">
|
||||
<el-input-number v-model="form.receivableAmount" :min="0" :precision="2" style="width: 100%;" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="应收款日期" prop="receivableDate">
|
||||
<el-date-picker
|
||||
v-model="form.receivableDate"
|
||||
type="date"
|
||||
placeholder="选择日期"
|
||||
style="width: 100%;"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-form-item label="交付日期" prop="deliveryDate">
|
||||
<el-date-picker
|
||||
v-model="form.deliveryDate"
|
||||
type="date"
|
||||
placeholder="选择日期"
|
||||
style="width: 100%;"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 更新状态对话框 -->
|
||||
<el-dialog v-model="statusDialogVisible" title="更新状态" width="400px">
|
||||
<el-form>
|
||||
<el-form-item label="状态">
|
||||
<el-select v-model="statusForm.status" placeholder="请选择状态" style="width: 100%;">
|
||||
<el-option label="待开发" value="pending" />
|
||||
<el-option label="开发中" value="developing" />
|
||||
<el-option label="已交付" value="delivered" />
|
||||
<el-option label="已完成" value="completed" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="statusDialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmitStatus">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 更新进度对话框 -->
|
||||
<el-dialog v-model="progressDialogVisible" title="更新进度" width="400px">
|
||||
<el-form>
|
||||
<el-form-item label="进度">
|
||||
<el-slider v-model="progressForm.progress" :min="0" :max="100" show-input />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="progressDialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmitProgress">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import {
|
||||
getRequirementList,
|
||||
createRequirement,
|
||||
updateRequirement,
|
||||
deleteRequirement,
|
||||
updateRequirementStatus,
|
||||
updateRequirementProgress
|
||||
} from '../../api/requirement'
|
||||
import { getProjectList } from '../../api/project'
|
||||
import { getCustomerList } from '../../api/customer'
|
||||
|
||||
// 搜索表单
|
||||
const searchForm = reactive({
|
||||
requirementName: '',
|
||||
projectId: null,
|
||||
customerId: null,
|
||||
status: ''
|
||||
})
|
||||
|
||||
// 表格数据
|
||||
const tableData = ref([])
|
||||
const loading = ref(false)
|
||||
|
||||
// 分页
|
||||
const page = reactive({
|
||||
current: 1,
|
||||
size: 10,
|
||||
total: 0
|
||||
})
|
||||
|
||||
// 项目选项
|
||||
const projectOptions = ref([])
|
||||
// 客户选项
|
||||
const customerOptions = ref([])
|
||||
|
||||
// 对话框
|
||||
const dialogVisible = ref(false)
|
||||
const formRef = ref(null)
|
||||
|
||||
// 表单数据
|
||||
const form = reactive({
|
||||
requirementId: null,
|
||||
requirementCode: '',
|
||||
requirementName: '',
|
||||
description: '',
|
||||
projectId: null,
|
||||
customerId: null,
|
||||
priority: 'normal',
|
||||
status: 'pending',
|
||||
estimatedHours: 0,
|
||||
actualHours: 0,
|
||||
plannedStart: null,
|
||||
plannedEnd: null,
|
||||
actualStart: null,
|
||||
actualEnd: null,
|
||||
deliveryDate: null,
|
||||
receivableAmount: 0,
|
||||
receivableDate: null
|
||||
})
|
||||
|
||||
// 表单验证规则
|
||||
const rules = {
|
||||
requirementCode: [
|
||||
{ required: true, message: '请输入需求编号', trigger: 'blur' }
|
||||
],
|
||||
requirementName: [
|
||||
{ required: true, message: '请输入需求名称', trigger: 'blur' }
|
||||
],
|
||||
projectId: [
|
||||
{ required: true, message: '请选择项目', trigger: 'change' }
|
||||
],
|
||||
customerId: [
|
||||
{ required: true, message: '请选择客户', trigger: 'change' }
|
||||
]
|
||||
}
|
||||
|
||||
// 状态对话框
|
||||
const statusDialogVisible = ref(false)
|
||||
const statusForm = reactive({
|
||||
requirementId: null,
|
||||
status: ''
|
||||
})
|
||||
|
||||
// 进度对话框
|
||||
const progressDialogVisible = ref(false)
|
||||
const progressForm = reactive({
|
||||
requirementId: null,
|
||||
progress: 0
|
||||
})
|
||||
|
||||
// 加载项目列表
|
||||
const loadProjects = async () => {
|
||||
try {
|
||||
const res = await getProjectList({ current: 1, size: 1000 })
|
||||
projectOptions.value = res.records || []
|
||||
} catch (error) {
|
||||
console.error('加载项目列表失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 加载客户列表
|
||||
const loadCustomers = async () => {
|
||||
try {
|
||||
const res = await getCustomerList({ current: 1, size: 1000 })
|
||||
customerOptions.value = res.records || []
|
||||
} catch (error) {
|
||||
console.error('加载客户列表失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 获取项目名称
|
||||
const getProjectName = (projectId) => {
|
||||
const project = projectOptions.value.find(p => p.projectId === projectId)
|
||||
return project ? project.projectName : '-'
|
||||
}
|
||||
|
||||
// 获取客户名称
|
||||
const getCustomerName = (customerId) => {
|
||||
const customer = customerOptions.value.find(c => c.customerId === customerId)
|
||||
return customer ? customer.customerName : '-'
|
||||
}
|
||||
|
||||
// 进度颜色
|
||||
const getProgressColor = (percentage) => {
|
||||
if (percentage < 30) return '#f56c6c'
|
||||
if (percentage < 70) return '#e6a23c'
|
||||
return '#67c23a'
|
||||
}
|
||||
|
||||
// 加载数据
|
||||
const fetchData = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const params = {
|
||||
current: page.current,
|
||||
size: page.size,
|
||||
requirementName: searchForm.requirementName || undefined,
|
||||
projectId: searchForm.projectId || undefined,
|
||||
customerId: searchForm.customerId || undefined,
|
||||
status: searchForm.status || undefined
|
||||
}
|
||||
const res = await getRequirementList(params)
|
||||
tableData.value = res.records
|
||||
page.total = res.total
|
||||
} catch (error) {
|
||||
console.error('加载数据失败:', error)
|
||||
ElMessage.error(error.message || '加载数据失败')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 搜索
|
||||
const handleSearch = () => {
|
||||
page.current = 1
|
||||
fetchData()
|
||||
}
|
||||
|
||||
// 重置
|
||||
const handleReset = () => {
|
||||
searchForm.requirementName = ''
|
||||
searchForm.projectId = null
|
||||
searchForm.customerId = null
|
||||
searchForm.status = ''
|
||||
page.current = 1
|
||||
fetchData()
|
||||
}
|
||||
|
||||
// 新增
|
||||
const handleAdd = () => {
|
||||
Object.assign(form, {
|
||||
requirementId: null,
|
||||
requirementCode: '',
|
||||
requirementName: '',
|
||||
description: '',
|
||||
projectId: null,
|
||||
customerId: null,
|
||||
priority: 'normal',
|
||||
status: 'pending',
|
||||
estimatedHours: 0,
|
||||
actualHours: 0,
|
||||
plannedStart: null,
|
||||
plannedEnd: null,
|
||||
actualStart: null,
|
||||
actualEnd: null,
|
||||
deliveryDate: null,
|
||||
receivableAmount: 0,
|
||||
receivableDate: null
|
||||
})
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
// 编辑
|
||||
const handleEdit = (row) => {
|
||||
Object.assign(form, {
|
||||
requirementId: row.requirementId,
|
||||
requirementCode: row.requirementCode,
|
||||
requirementName: row.requirementName,
|
||||
description: row.description,
|
||||
projectId: row.projectId,
|
||||
customerId: row.customerId,
|
||||
priority: row.priority,
|
||||
status: row.status,
|
||||
estimatedHours: row.estimatedHours,
|
||||
actualHours: row.actualHours,
|
||||
plannedStart: row.plannedStart,
|
||||
plannedEnd: row.plannedEnd,
|
||||
actualStart: row.actualStart,
|
||||
actualEnd: row.actualEnd,
|
||||
deliveryDate: row.deliveryDate,
|
||||
receivableAmount: row.receivableAmount,
|
||||
receivableDate: row.receivableDate
|
||||
})
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const handleSubmit = async () => {
|
||||
if (!formRef.value) return
|
||||
|
||||
try {
|
||||
await formRef.value.validate()
|
||||
} catch (error) {
|
||||
ElMessage.warning('请检查表单填写是否完整')
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
if (form.requirementId) {
|
||||
await updateRequirement(form.requirementId, form)
|
||||
ElMessage.success('更新成功')
|
||||
} else {
|
||||
await createRequirement(form)
|
||||
ElMessage.success('创建成功')
|
||||
}
|
||||
dialogVisible.value = false
|
||||
await fetchData()
|
||||
} catch (error) {
|
||||
console.error('保存失败:', error)
|
||||
ElMessage.error(error.message || '操作失败')
|
||||
}
|
||||
}
|
||||
|
||||
// 更新状态
|
||||
const handleUpdateStatus = (row) => {
|
||||
statusForm.requirementId = row.requirementId
|
||||
statusForm.status = row.status
|
||||
statusDialogVisible.value = true
|
||||
}
|
||||
|
||||
// 提交状态
|
||||
const handleSubmitStatus = async () => {
|
||||
try {
|
||||
await updateRequirementStatus(statusForm.requirementId, statusForm.status)
|
||||
ElMessage.success('状态更新成功')
|
||||
statusDialogVisible.value = false
|
||||
await fetchData()
|
||||
} catch (error) {
|
||||
console.error('状态更新失败:', error)
|
||||
ElMessage.error(error.message || '状态更新失败')
|
||||
}
|
||||
}
|
||||
|
||||
// 更新进度
|
||||
const handleUpdateProgress = (row) => {
|
||||
progressForm.requirementId = row.requirementId
|
||||
progressForm.progress = row.progress
|
||||
progressDialogVisible.value = true
|
||||
}
|
||||
|
||||
// 提交进度
|
||||
const handleSubmitProgress = async () => {
|
||||
try {
|
||||
await updateRequirementProgress(progressForm.requirementId, progressForm.progress)
|
||||
ElMessage.success('进度更新成功')
|
||||
progressDialogVisible.value = false
|
||||
await fetchData()
|
||||
} catch (error) {
|
||||
console.error('进度更新失败:', error)
|
||||
ElMessage.error(error.message || '进度更新失败')
|
||||
}
|
||||
}
|
||||
|
||||
// 删除
|
||||
const handleDelete = async (row) => {
|
||||
try {
|
||||
await ElMessageBox.confirm('确定要删除该需求吗?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
})
|
||||
|
||||
await deleteRequirement(row.requirementId)
|
||||
ElMessage.success('删除成功')
|
||||
|
||||
// 如果是最后一条且不是第一页,返回上一页
|
||||
if (tableData.value.length === 1 && page.current > 1) {
|
||||
page.current--
|
||||
}
|
||||
|
||||
await fetchData()
|
||||
} catch (error) {
|
||||
if (error !== 'cancel') {
|
||||
console.error('删除失败:', error)
|
||||
ElMessage.error(error.message || '删除失败')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
loadProjects()
|
||||
loadCustomers()
|
||||
fetchData()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.requirement-container {
|
||||
padding: 20px;
|
||||
}
|
||||
</style>
|
||||
Loading…
x
Reference in New Issue
Block a user