月计划管理模块接口调试

This commit is contained in:
BianLzhaoMin 2025-12-25 15:17:04 +08:00
parent 5298bff988
commit c9093f203c
10 changed files with 318 additions and 117 deletions

View File

@ -18,14 +18,23 @@ export function getPersonNatureAndCategoryAndPositionSelectAPI(data) {
})
}
// 公共下拉选数据 - 获取工作量类别
// export function getWorkloadCategorySelectAPI(data) {
// return request({
// url: '/workloadCategory/getWorkloadCategorySelect',
// method: 'GET',
// params: data,
// })
// }
// 公共下拉选数据 - 获取专业,类型,类别 0 1 2 分别对应专业,类型,类别
export function getMajorTypeCategorySelectAPI(data) {
return request({
url: '/planMajor/getPlanMajorListSelect',
method: 'GET',
params: data,
})
}
// 获取工作量类别下拉
export function getPlanMajorListSelectAPI(data = {}) {
return request({
url: '/workloadCategory/getWorkloadCategoryListSelect',
method: 'GET',
params: data,
})
}
// 公共下拉选数据 - 获取人员列表
export function getPersonnelCommonListAPI(data) {

View File

@ -21,11 +21,19 @@ export function addMonthlyPlanAPI(data) {
// 月计划管理- 修改
export function updateMonthlyPlanAPI(data) {
return request({
url: '/monthlyPlan/updatePersonnel',
url: '/monthlyPlan/updateMonthlyPlan',
method: 'POST',
data,
})
}
// 月计划管理- 获取详情
export function getMonthlyPlanDetailAPI(data) {
return request({
url: '/monthlyPlan/getMonthlyPlanById',
method: 'GET',
params: data,
})
}
// 月计划管理- 删除
export function delMonthlyPlanAPI(data) {

View File

@ -7,6 +7,10 @@ const useOptionsStore = defineStore('options', {
personCategoryOptions: [], // 人员分类
inspectionStationOptions: [], // 运检站
personnelCommonOptions: [], // 人员列表
majorTypeCategoryOptions: [], // 专业
planBusinessTypeOptions: [], // 业务类型
planCategoryOptions: [], // 类别
planWorkLoadCategoryOptions: [], // 工作量类别
}),
actions: {
// 通用的设置方法,方便 Hook 调用

View File

@ -57,6 +57,7 @@ import {
delBusinessTypeAPI,
updateBusinessTypeAPI,
} from '@/api/basicManage/businessType'
import { bus, BUS_EVENTS } from '@/utils/bus'
import config from './config'
import ComTable from '@/components/ComTable/index.vue'
import ComButton from '@/components/ComButton/index.vue'
@ -111,6 +112,7 @@ const actionColumns = [
if (result.code === 200) {
proxy.$modal.msgSuccess('删除成功')
comTableRef.value?.refresh() //
bus.emit(BUS_EVENTS.REFRESH_OPTIONS, 'planBusinessTypeOptions') //
}
})
},
@ -150,6 +152,7 @@ const onHandleSave = async () => {
addAndEditFormRef.value.resetFields() //
dialogConfig.outerVisible = false
comTableRef.value?.refresh() //
bus.emit(BUS_EVENTS.REFRESH_OPTIONS, 'planBusinessTypeOptions') //
}
} catch (error) {
console.error('表单校验失败或请求错误:', error)

View File

@ -66,6 +66,7 @@ import {
delPlanCategoryAPI,
updatePlanCategoryAPI,
} from '@/api/basicManage/planCategory.js'
import { bus, BUS_EVENTS } from '@/utils/bus'
import config from './config'
import ComTable from '@/components/ComTable/index.vue'
import ComButton from '@/components/ComButton/index.vue'
@ -120,6 +121,7 @@ const actionColumns = [
if (result.code === 200) {
proxy.$modal.msgSuccess('删除成功')
comTableRef.value?.refresh() //
bus.emit(BUS_EVENTS.REFRESH_OPTIONS, 'planCategoryOptions') //
}
})
},
@ -159,6 +161,7 @@ const onHandleSave = async () => {
addAndEditFormRef.value.resetFields() //
dialogConfig.outerVisible = false
comTableRef.value?.refresh() //
bus.emit(BUS_EVENTS.REFRESH_OPTIONS, 'planCategoryOptions') //
}
} catch (error) {
console.error('表单校验失败或请求错误:', error)

View File

@ -66,6 +66,7 @@ import {
delPlanProfessionalAPI,
updatePlanProfessionalAPI,
} from '@/api/basicManage/planProfessional'
import { bus, BUS_EVENTS } from '@/utils/bus'
import config from './config'
import ComTable from '@/components/ComTable/index.vue'
import ComButton from '@/components/ComButton/index.vue'
@ -120,6 +121,7 @@ const actionColumns = [
if (result.code === 200) {
proxy.$modal.msgSuccess('删除成功')
comTableRef.value?.refresh() //
bus.emit(BUS_EVENTS.REFRESH_OPTIONS, 'majorTypeCategoryOptions') //
}
})
},
@ -159,6 +161,7 @@ const onHandleSave = async () => {
addAndEditFormRef.value.resetFields() //
dialogConfig.outerVisible = false
comTableRef.value?.refresh() //
bus.emit(BUS_EVENTS.REFRESH_OPTIONS, 'majorTypeCategoryOptions') //
}
} catch (error) {
console.error('表单校验失败或请求错误:', error)

View File

@ -84,6 +84,7 @@ import {
updateWorkloadCategoryAPI,
} from '@/api/basicManage/workloadCategory.js'
import { yuanToFen, fenToYuan } from '@/utils/ruoyi'
import { bus, BUS_EVENTS } from '@/utils/bus'
import config from './config'
import ComTable from '@/components/ComTable/index.vue'
import ComButton from '@/components/ComButton/index.vue'
@ -140,6 +141,7 @@ const actionColumns = [
if (result.code === 200) {
proxy.$modal.msgSuccess('删除成功')
comTableRef.value?.refresh() //
bus.emit(BUS_EVENTS.REFRESH_OPTIONS, 'planWorkLoadCategoryOptions') //
}
})
},
@ -180,6 +182,7 @@ const onHandleSave = async () => {
addAndEditFormRef.value.resetFields() //
dialogConfig.outerVisible = false
comTableRef.value?.refresh() //
bus.emit(BUS_EVENTS.REFRESH_OPTIONS, 'planWorkLoadCategoryOptions') //
}
} catch (error) {
console.error('表单校验失败或请求错误:', error)

View File

@ -1,4 +1,5 @@
import { reactive } from 'vue'
import dayjs from 'dayjs'
// 静态选项(可后续替换为接口下拉)
const stationOptions = [
@ -67,18 +68,45 @@ export const tableColumns = [
{ prop: 'businessTypeId', label: '业务类型', fixed: true },
{ prop: 'projectName', label: '项目名称', fixed: true },
{ prop: 'workContent', label: '工作任务' },
{ prop: 'riskLevelName', label: '风险等级' },
{ prop: 'riskLevel', label: '风险等级' },
{ prop: 'planCategoryId', label: '类别' },
{ prop: 'workAmount', label: '工作量', width: '140' },
{ prop: 'workAmount', label: '工作量', width: '180', slot: 'workAmount' },
{ prop: 'towerBaseNumber', label: '基塔数' },
{ prop: 'plannedStartTime', label: '计划开始时间', width: '140' },
{ prop: 'plannedEndTime', label: '计划结束时间', width: '140' },
{ prop: 'planPersonnel', label: '计划投入管理人员数量' },
{ prop: 'planSkilledWorkerDay', label: '计划投入管理人员工日' },
{
prop: 'planPersonnel',
label: '计划投入管理人员数量',
formatter: (row) => {
return row.personneltList?.length || 0
},
},
{ prop: 'planCarNum', label: '计划投入管理人员车辆数' },
{ prop: 'planSkilledWorkerNum', label: '计划投入熟练工人员数量' },
{
prop: 'planSkilledWorkerDay',
label: '计划投入熟练工人员工日',
// 使用dayjs 根据开始时间和结束时间计算出工日 * 计划投入熟练工人员工日
formatter: (row) => {
return (
(dayjs(row.plannedEndTime).diff(dayjs(row.plannedStartTime), 'day') + 1) *
row.planSkilledWorkerDay
)
},
},
{ prop: 'planAuxiliaryWorkerNum', label: '计划投入辅助工人员数量' },
{ prop: 'planAuxiliaryWorkerDay', label: '计划投入施工人员工日' },
{
prop: 'planAuxiliaryWorkerDay',
label: '计划投入辅助工人员工日',
// 使用dayjs 根据开始时间和结束时间计算出工日 * 计划投入熟练工人员工日
formatter: (row) => {
return (
(dayjs(row.plannedEndTime).diff(dayjs(row.plannedStartTime), 'day') + 1) *
row.planAuxiliaryWorkerDay
)
},
},
{ prop: 'planSubCarNum', label: '计划投入分包车辆数' },
{ prop: 'actualWorkingDay', label: '实际工作天数' },
]

View File

@ -31,10 +31,10 @@
clearable
>
<el-option
:key="item.value"
:label="item.label"
:value="item.value"
v-for="item in majorOptions"
:key="item.planMajorId"
:label="item.planMajorName"
:value="item.planMajorId"
v-for="item in majorTypeCategoryOptions"
/>
</el-select>
</el-form-item>
@ -50,10 +50,10 @@
clearable
>
<el-option
v-for="item in businessTypeOptions"
:key="item.value"
:label="item.label"
:value="item.value"
v-for="item in planBusinessTypeOptions"
:key="item.planMajorId"
:label="item.planMajorName"
:value="item.planMajorId"
/>
</el-select>
</el-form-item>
@ -95,10 +95,10 @@
clearable
>
<el-option
v-for="item in riskLevelOptions"
:key="item.value"
:label="item.label"
:value="item.value"
v-for="item in planCategoryOptions"
:key="item.planMajorId"
:label="item.planMajorName"
:value="item.planMajorId"
/>
</el-select>
</el-form-item>
@ -106,22 +106,23 @@
</el-row>
<el-row :gutter="24">
<template v-for="(item, index) in formData.workLoadList" :key="index">
<template v-for="(item, index) in formData.workloadList" :key="index">
<el-col :span="8">
<el-form-item
:label="index == 0 ? '工作量' : ''"
:prop="`workLoadList.${index}.workloadCategoryId`"
:prop="`workloadList.${index}.workloadCategoryId`"
>
<el-select
clearable
v-model="item.workloadCategoryId"
placeholder="请选择工作量类别"
v-model="item.workloadCategoryId"
@change="onChangeWorkLoadCategory($event, index)"
>
<el-option
:key="item.value"
:label="item.label"
:value="item.value"
v-for="item in workLoadCategoryOptions"
:key="item.workloadCategoryId"
:value="item.workloadCategoryId"
:label="item.workloadCategoryName"
v-for="item in planWorkLoadCategoryOptions"
/>
</el-select>
</el-form-item>
@ -129,12 +130,13 @@
<el-col :span="4">
<el-form-item
label-width="0"
:prop="`workLoadList.${index}.workloadNum`"
:prop="`workloadList.${index}.workloadNum`"
>
<el-input
v-model="item.workloadNum"
clearable
style="width: 240px"
placeholder="输入数量"
v-model="item.workloadNum"
>
<template #suffix>
<el-button
@ -199,12 +201,12 @@
<el-row :gutter="24">
<el-col :span="12">
<el-form-item label="计划投入管理人员" prop="planPersonnel">
<el-form-item label="计划投入管理人员" prop="planPersonnelList">
<el-input
v-model="selectedManagerNames"
readonly
placeholder="点击选择管理人员"
@click="onOpenPersonPicker"
v-model="selectedManagerNames"
>
<template #suffix>
<el-icon
@ -385,7 +387,7 @@
type="primary"
size="small"
plain
:disabled="!day.isInRange || !formData.planPersonnel.length"
:disabled="!day.isInRange || !formData.planPersonnelList.length"
@click="onFillManagersForDay(day.date)"
>
安排人员
@ -513,8 +515,12 @@
import { ref, reactive, computed, getCurrentInstance, nextTick } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { updatePlanAPI } from '@/api/planMange/plan.js'
import { getPersonnelCommonListAPI } from '@/api/common.js'
import { listPlanProfessionalAPI } from '@/api/basicManage/planProfessional'
import {
getPersonnelCommonListAPI,
getMajorTypeCategorySelectAPI,
getPlanMajorListSelectAPI,
} from '@/api/common.js'
import { updateMonthlyPlanAPI, getMonthlyPlanDetailAPI } from '@/api/planMange/monthlyPlan.js'
import { Search } from '@element-plus/icons-vue'
import { useOptions } from '@/hooks/useOptions'
import ComButton from '@/components/ComButton/index.vue'
@ -536,6 +542,38 @@ const { options: personnelCommonOptions } = useOptions(
{},
)
//
const { options: majorTypeCategoryOptions } = useOptions(
'majorTypeCategoryOptions',
getMajorTypeCategorySelectAPI,
{
category: 0,
},
)
//
const { options: planBusinessTypeOptions } = useOptions(
'planBusinessTypeOptions',
getMajorTypeCategorySelectAPI,
{
category: 1,
},
)
//
const { options: planCategoryOptions } = useOptions(
'planCategoryOptions',
getMajorTypeCategorySelectAPI,
{
category: 2,
},
)
//
const { options: planWorkLoadCategoryOptions } = useOptions(
'planWorkLoadCategoryOptions',
getPlanMajorListSelectAPI,
{},
)
const mode = computed(() => route.query.mode || 'add')
const isDetail = computed(() => mode.value === 'detail')
@ -569,7 +607,8 @@ const getInitFormData = () => ({
businessTypeId: null, //
planCategoryId: null, //
towerBaseNumber: '', //
// planPersonnel: [], //
planPersonnelList: [], //
planPersonnel: [], //
planCarNum: '', //
planSkilledWorkerNum: '', //
planAuxiliaryWorkerNum: '', //
@ -577,9 +616,11 @@ const getInitFormData = () => ({
planSkilledWorkerDay: '', //
planSubCarNum: '', //
actualWorkingDay: '', //
workLoadList: [
workloadList: [
{
workloadCategoryId: '', // id
workloadCategoryName: '', //
unitPrice: '', //
workloadNum: '', //
},
@ -595,8 +636,6 @@ const stationOptions = [
{ label: '大理运检站', value: 2 },
]
const majorOptions = ref([])
const businessTypeOptions = [
{ label: '日常巡视', value: 1 },
{ label: '缺陷处理', value: 2 },
@ -614,14 +653,13 @@ const rules = {
riskLevel: [{ required: true, message: '请选择风险等级', trigger: 'change' }],
planCategoryId: [{ required: true, message: '请选择类别', trigger: 'change' }],
towerBaseNumber: [{ required: true, message: '请输入基塔数', trigger: 'blur' }],
planPersonnel: [{ required: true, message: '请选择计划投入管理人员', trigger: 'blur' }],
planPersonnelWorkDays: [
{ required: true, message: '请输入计划投入管理人员工日', trigger: 'blur' },
],
planPersonnelList: [{ required: true, message: '请选择计划投入管理人员', trigger: 'blur' }],
planCarNum: [{ required: true, message: '请输入计划投入管理人员车辆数', trigger: 'blur' }],
planSkilledWorkerNum: [
{ required: true, message: '请输入计划投入熟练工人员数量', trigger: 'blur' },
],
planAuxiliaryWorkerNum: [
{ required: true, message: '请输入计划投入辅助工人员数量', trigger: 'blur' },
],
@ -636,64 +674,71 @@ const rules = {
}
const onBack = () => {
router.back()
}
const onSubmit = () => {
formRef.value.validate(async (valid, fields) => {
if (!valid) {
//
if (fields && Object.keys(fields).length) {
const firstProp = Object.keys(fields)[0]
formRef.value.scrollToField(firstProp)
}
return
}
//
const {
inspectionStationName,
projectName,
workContent,
plannedStartTime,
plannedEndTime,
...submitData
} = formData.value
// personnelArrangementList
submitData.personnelArrangementList = Object.keys(dayAssignments.value).map((date) => {
const managers = dayAssignments.value[date] || []
return {
day: date,
personnelNames: managers.map((p) => p.name).join('、'),
}
})
console.log('submitData组装后的参数', submitData)
// const API = mode.value === 'edit' ? updatePlanAPI : addPlanAPI
// try {
// const res = await API(submitData)
// if (res.code === 200) {
// proxy.$modal.msgSuccess(mode.value === 'edit' ? '' : '')
// onBack()
// }
// } catch (error) {
// console.error(':', error)
// }
// router.back()
router.push({
path: '/plan/monthlyPlan',
})
}
const onSubmit = async () => {
try {
await formRef.value.validate(async (valid, fields) => {
if (!valid) {
//
if (fields && Object.keys(fields).length) {
const firstProp = Object.keys(fields)[0]
formRef.value.scrollToField(firstProp)
}
return
}
//
const {
inspectionStationName,
projectName,
workContent,
plannedStartTime,
plannedEndTime,
planPersonnelList,
...submitData
} = formData.value
// personnelArrangementList
submitData.personnelArrangementList = Object.keys(dayAssignments.value).map((date) => {
const managers = dayAssignments.value[date] || []
return {
day: date,
personnelNames: managers.map((p) => p.name).join(','),
}
})
submitData.planPersonnel = planPersonnelList.map((item) => item.id).join(',')
console.log('submitData组装后的参数', submitData)
const result = await updateMonthlyPlanAPI(submitData)
if (result.code === 200) {
proxy.$modal.msgSuccess('编辑成功')
onBack()
}
console.log('result--', result)
})
} catch (error) {
return Promise.reject(error)
}
}
const onAddWorkLoad = () => {
formData.value.workLoadList.push({
formData.value.workloadList.push({
workloadCategoryId: '',
workloadCategoryName: '',
unitPrice: '',
workloadNum: '',
})
}
const onDeleteWorkLoad = (index) => {
formData.value.workLoadList.splice(index, 1)
formData.value.workloadList.splice(index, 1)
}
//
@ -737,7 +782,7 @@ const filteredPersons = computed(() => {
})
const selectedManagerNames = computed(() =>
formData.value.planPersonnel.map((item) => item.name).join('、'),
formData.value.planPersonnelList.map((item) => item.name).join('、'),
)
const onOpenPersonPicker = async () => {
@ -747,13 +792,13 @@ const onOpenPersonPicker = async () => {
if (personTableRef.value) {
personTableRef.value.clearSelection()
personList.value.forEach((row) => {
const exists = formData.value.planPersonnel.find((item) => item.id === row.id)
const exists = formData.value.planPersonnelList.find((item) => item.id === row.id)
if (exists) {
personTableRef.value.toggleRowSelection(row, true)
}
})
}
managerDialog.selected = [...formData.value.planPersonnel]
managerDialog.selected = [...formData.value.planPersonnelList]
}
const onManagerSelectionChange = (rows) => {
@ -774,7 +819,7 @@ const onClearManagers = () => {
}
const onConfirmManager = () => {
formData.value.planPersonnel = [...managerDialog.selected]
formData.value.planPersonnelList = [...managerDialog.selected]
managerDialog.visible = false
managerDialogConfig.outerVisible = false
}
@ -819,8 +864,8 @@ const calendarDays = computed(() => {
//
const onFillManagersForDay = (date) => {
if (!formData.value.planPersonnel || !formData.value.planPersonnel.length) return
dayAssignments.value[date] = formData.value.planPersonnel.map((p) => ({ ...p }))
if (!formData.value.planPersonnelList || !formData.value.planPersonnelList.length) return
dayAssignments.value[date] = formData.value.planPersonnelList.map((p) => ({ ...p }))
}
//
@ -836,25 +881,114 @@ const onRemovePersonFromDay = (date, person) => {
dayAssignments.value[date] = list.filter((item) => item.id !== person.id)
}
//
const getMajorOptions = async () => {
const res = await listPlanProfessionalAPI({
pageNum: 1,
pageSize: 1000,
category: 0,
})
//
const onChangeWorkLoadCategory = (event, index) => {
const workloadCategoryId = event
const workloadCategory = planWorkLoadCategoryOptions.value.find(
(item) => item.workloadCategoryId === workloadCategoryId,
)
formData.value.workloadList[index].unitPrice = workloadCategory.unitPrice
formData.value.workloadList[index].workloadCategoryName = workloadCategory.workloadCategoryName
}
console.log('专业列表', res)
if (res.code === 200) {
majorOptions.value = res.rows?.map((item) => ({
label: item.planMajorName,
value: item.planMajorId,
}))
//
const getDetail = async () => {
const result = await getMonthlyPlanDetailAPI({ monthlyPlanId: route.query.monthlyPlanId })
console.log('result--', result)
if (result.code === 200 && result.data) {
const data = result.data
// 1.
formData.value.monthlyPlanId = data.monthlyPlanId
formData.value.planMajorId = data.planMajorId
formData.value.businessTypeId = data.businessTypeId
formData.value.planCategoryId = data.planCategoryId
formData.value.towerBaseNumber = data.towerBaseNumber || ''
formData.value.planCarNum = data.planCarNum || ''
formData.value.planSkilledWorkerNum = data.planSkilledWorkerNum || ''
formData.value.planAuxiliaryWorkerNum = data.planAuxiliaryWorkerNum || ''
formData.value.planAuxiliaryWorkerDay = data.planAuxiliaryWorkerDay || ''
formData.value.planSkilledWorkerDay = data.planSkilledWorkerDay || ''
formData.value.planSubCarNum = data.planSubCarNum || ''
formData.value.actualWorkingDay = data.actualWorkingDay || ''
formData.value.riskLevel = data.riskLevel
// 2.
if (data.inspectionStationName) {
formData.value.inspectionStationName = data.inspectionStationName
}
if (data.projectName) {
formData.value.projectName = data.projectName
}
if (data.workContent) {
formData.value.workContent = data.workContent
}
if (data.plannedStartTime) {
formData.value.plannedStartTime = data.plannedStartTime
}
if (data.plannedEndTime) {
formData.value.plannedEndTime = data.plannedEndTime
}
// 3. planPersonnel "1,5,6" planPersonnelList
if (data.planPersonnel && data.personneltList && data.personneltList.length > 0) {
const personnelIds = data.planPersonnel.split(',').map((id) => String(id.trim()))
formData.value.planPersonnelList = data.personneltList.filter((person) =>
personnelIds.includes(String(person.id)),
)
} else {
formData.value.planPersonnelList = []
}
// 4.
if (data.workloadList && data.workloadList.length > 0) {
formData.value.workloadList = data.workloadList.map((item) => ({
workloadCategoryId: item.workloadCategoryId || '',
workloadCategoryName: item.workloadCategoryName || '',
unitPrice: item.unitPrice || '',
workloadNum: item.workloadNum || '',
}))
} else {
//
formData.value.workloadList = [
{
workloadCategoryId: '',
workloadCategoryName: '',
unitPrice: '',
workloadNum: '',
},
]
}
// 5. personnelArrangementList dayAssignments
dayAssignments.value = {}
if (
data.personnelArrangementList &&
data.personnelArrangementList.length > 0 &&
data.personneltList
) {
data.personnelArrangementList.forEach((arrangement) => {
const day = arrangement.day
if (day && arrangement.personnelNames) {
//
const personnelNames = arrangement.personnelNames
.split(',')
.map((name) => name.trim())
const personnelObjects = data.personneltList.filter((person) =>
personnelNames.includes(person.name),
)
if (personnelObjects.length > 0) {
dayAssignments.value[day] = personnelObjects
}
}
})
}
}
}
onMounted(() => {
getMajorOptions()
getDetail()
})
</script>

View File

@ -37,6 +37,13 @@
导出工作量汇总表
</ComButton>
</template>
<template #workAmount="{ row }">
<template v-for="(item, index) in row.workloadList" :key="index">
<span>{{ item.workloadCategoryName || '类型' }} {{ item.workloadNum }}</span>
<span v-if="index !== row.workloadList.length - 1"></span>
</template>
</template>
</ComTable>
<ComDialog :dialog-config="dialogConfig" @closeDialogOuter="onCloseDialogOuter">
@ -147,12 +154,11 @@ const onHandleSave = async () => {
const paramsList = addFormRef.value.getSelectedTasks().map((item) => ({
planManagementId: item.planManagementId,
planManagementMonth: item.planManagementMonth,
monthlyPlan: item.planManagementMonth,
inspectionStationId: item.inspectionStationId,
inspectionStationName: item.inspectionStationName,
projectName: item.projectName,
workContent: item.workContent,
planManagementMonth: item.planManagementMonth,
plannedStartTime: item.stareDate,
plannedEndTime: item.endDate,
riskLevel: item.riskLevel,