This commit is contained in:
parent
0d286b2b41
commit
5ecde86836
|
|
@ -111,7 +111,7 @@ export const constantRoutes = [
|
|||
component: () => import('@/views/planMange/dailyPlan/edit.vue'),
|
||||
name: 'DailyPlanEdit',
|
||||
meta: {
|
||||
title: '日计划',
|
||||
title: '日完成情况',
|
||||
activeMenu: '/plan/dailyPlan', // 保持左侧高亮在列表菜单
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ export default {
|
|||
},
|
||||
{
|
||||
prop: 'settlementUnitPrice',
|
||||
label: '结算单价',
|
||||
label: '预估单价',
|
||||
slot: 'settlementUnitPrice',
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
<template #unitPrice="{ row }">
|
||||
<span>¥{{ fenToYuan(row.unitPrice) }}</span>
|
||||
</template>
|
||||
<!-- 结算单价列插槽 -->
|
||||
<!-- 预估单价列插槽 -->
|
||||
<template #settlementUnitPrice="{ row }">
|
||||
<span>¥{{ fenToYuan(row.settlementUnitPrice) }}</span>
|
||||
</template>
|
||||
|
|
@ -59,7 +59,7 @@
|
|||
</el-input-number>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="结算单价" prop="settlementUnitPrice">
|
||||
<el-form-item label="预估单价" prop="settlementUnitPrice">
|
||||
<el-input-number
|
||||
style="width: 100%"
|
||||
:min="0.1"
|
||||
|
|
@ -129,7 +129,7 @@ const addAndEditForm = ref(getInitFormData())
|
|||
const addAndEditRules = ref({
|
||||
workloadCategoryName: [{ required: true, message: '请输入工作量类别名称', trigger: 'blur' }],
|
||||
unitPrice: [{ required: true, message: '请输入绩效单价', trigger: 'blur' }],
|
||||
settlementUnitPrice: [{ required: true, message: '请输入结算单价', trigger: 'blur' }],
|
||||
settlementUnitPrice: [{ required: true, message: '请输入预估单价', trigger: 'blur' }],
|
||||
})
|
||||
|
||||
const actionColumns = [
|
||||
|
|
|
|||
|
|
@ -48,58 +48,86 @@ export const tableColumns = [
|
|||
{ prop: 'projectName', label: '项目名称', fixed: true, width: '140' },
|
||||
{ prop: 'workContent', label: '工作任务', width: '140' },
|
||||
{ prop: 'riskLevel', label: '风险等级', width: '80' },
|
||||
{ prop: 'plannedWorkload', label: '计划工作量(基)', width: '80' },
|
||||
// { prop: 'plannedWorkload', label: '计划工作量(基)', width: '80' },
|
||||
]
|
||||
export const tableColumns_1 = [
|
||||
{
|
||||
prop: 'stationName',
|
||||
label: '拟投入作业人员数量',
|
||||
fixed: false,
|
||||
width: '80',
|
||||
// {
|
||||
// prop: 'stationName',
|
||||
// label: '拟投入作业人员数量',
|
||||
// fixed: false,
|
||||
// width: '80',
|
||||
|
||||
formatter: (row) => {
|
||||
return row.proposedPersonnelList?.filter((item) => item.dataSource == 0).length || ''
|
||||
},
|
||||
},
|
||||
// formatter: (row) => {
|
||||
// return row.proposedPersonnelList?.filter((item) => item.dataSource == 0).length || ''
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// prop: 'majorName',
|
||||
// label: '拟投入作业人员姓名',
|
||||
// fixed: false,
|
||||
// width: '200',
|
||||
// formatter: (row) => {
|
||||
// return (
|
||||
// row.proposedPersonnelList
|
||||
// ?.filter((item) => item.dataSource == 0)
|
||||
// .map((item) => item.name)
|
||||
// .join(',') || ''
|
||||
// )
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// prop: 'proposedLongTimeCar',
|
||||
// label: '拟投入车辆',
|
||||
// fixed: false,
|
||||
// width: '200',
|
||||
// slot: 'proposedLongTimeCar',
|
||||
// },
|
||||
// {
|
||||
// prop: 'projectName',
|
||||
// label: '实际投入作业人员数量',
|
||||
// fixed: false,
|
||||
// width: '80',
|
||||
// formatter: (row) => {
|
||||
// return row.proposedPersonnelList?.filter((item) => item.dataSource == 1).length || ''
|
||||
// },
|
||||
// },
|
||||
{
|
||||
prop: 'majorName',
|
||||
label: '拟投入作业人员姓名',
|
||||
prop: 'workTask',
|
||||
label: '实际投入全民人员姓名',
|
||||
fixed: false,
|
||||
width: '200',
|
||||
formatter: (row) => {
|
||||
return (
|
||||
row.proposedPersonnelList
|
||||
?.filter((item) => item.dataSource == 0)
|
||||
?.filter((item) => item.dataSource == 1 && item.personnelClassificationName.includes('全民'))
|
||||
.map((item) => item.name)
|
||||
.join(',') || ''
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
prop: 'proposedLongTimeCar',
|
||||
label: '拟投入车辆',
|
||||
fixed: false,
|
||||
width: '200',
|
||||
slot: 'proposedLongTimeCar',
|
||||
},
|
||||
{
|
||||
prop: 'projectName',
|
||||
label: '实际投入作业人员数量',
|
||||
fixed: false,
|
||||
width: '80',
|
||||
formatter: (row) => {
|
||||
return row.proposedPersonnelList?.filter((item) => item.dataSource == 1).length || ''
|
||||
},
|
||||
},
|
||||
{
|
||||
prop: 'workTask',
|
||||
label: '实际投入作业人员姓名',
|
||||
label: '实际投入派遣人员姓名',
|
||||
fixed: false,
|
||||
width: '200',
|
||||
formatter: (row) => {
|
||||
return (
|
||||
row.proposedPersonnelList
|
||||
?.filter((item) => item.dataSource == 1)
|
||||
?.filter((item) => item.dataSource == 1 && item.personnelClassificationName.includes('派遣'))
|
||||
.map((item) => item.name)
|
||||
.join(',') || ''
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
prop: 'workTask',
|
||||
label: '实际投入海峡人员姓名',
|
||||
fixed: false,
|
||||
width: '200',
|
||||
formatter: (row) => {
|
||||
return (
|
||||
row.proposedPersonnelList
|
||||
?.filter((item) => item.dataSource == 1 && item.personnelClassificationName.includes('海峡'))
|
||||
.map((item) => item.name)
|
||||
.join(',') || ''
|
||||
)
|
||||
|
|
@ -115,7 +143,7 @@ export const tableColumns_1 = [
|
|||
// return `长租车${row.actualLongTimeCar}辆,临租车${row.actualTemporaryCar}辆` || ''
|
||||
// },
|
||||
},
|
||||
{ prop: 'actualWorkContent', label: '实际完成工作内容', fixed: false, width: '200' },
|
||||
// { prop: 'actualWorkContent', label: '实际完成工作内容', fixed: false, width: '200' },
|
||||
{ prop: 'actualWorkload', label: '实际完成工作量(基)', fixed: false, width: '80' },
|
||||
{
|
||||
prop: 'completionPercentage',
|
||||
|
|
@ -131,6 +159,7 @@ export const tableColumns_1 = [
|
|||
{ prop: 'planChanges', label: '计划变更及未完成情况说明', fixed: false, width: '200' },
|
||||
]
|
||||
export const tableColumns_2 = [
|
||||
{ prop: 'plannedWorkload', label: '计划工作量(基)', width: '80' },
|
||||
{
|
||||
prop: 'stationName',
|
||||
label: '拟投入高处作业人员数量',
|
||||
|
|
|
|||
|
|
@ -196,6 +196,7 @@ const { options: personnelCommonOptions } = useOptions(
|
|||
|
||||
const mode = computed(() => route.query.mode || 'edit')
|
||||
const isDetail = computed(() => mode.value === 'detail')
|
||||
const personSubType = ref(null)
|
||||
|
||||
// 获取日计划类型:0-运行,1-检修,2-项目部
|
||||
const dayPlanType = computed(() => {
|
||||
|
|
@ -223,9 +224,9 @@ const pageTitle = computed(() => {
|
|||
2: '项目部',
|
||||
}
|
||||
const typeName = typeMap[dayPlanType.value] || '运行'
|
||||
if (mode.value === 'edit') return `编辑日计划(${typeName})`
|
||||
if (mode.value === 'detail') return `日计划详情(${typeName})`
|
||||
return `新增日计划(${typeName})`
|
||||
if (mode.value === 'edit') return `编辑日完成情况(${typeName})`
|
||||
if (mode.value === 'detail') return `日完成情况详情(${typeName})`
|
||||
return `新增日完成情况(${typeName})`
|
||||
})
|
||||
|
||||
const baseFormRef = ref(null)
|
||||
|
|
@ -256,6 +257,9 @@ const getRunFormData = () => ({
|
|||
proposedTemporaryCar: null, // 拟投入临租车
|
||||
// 实际完成情况
|
||||
actualPersonnelList: [], // 实际入作业人员(数组,暂时不确定字段名)
|
||||
actualNationPersonnelList: [], // 实际投入全民员工(数组)
|
||||
actualDispatchPersonnelList: [], // 实际投入派遣员工(数组)
|
||||
actualOverseasPersonnelList: [], // 实际投入海峡员工(数组)
|
||||
actualPersonnel: '', // 实际入作业人员(字符串,提交时使用)
|
||||
actualLongTimeCar: null, // 实际入长租车
|
||||
actualTemporaryCar: null, // 实际入临租车
|
||||
|
|
@ -264,6 +268,17 @@ const getRunFormData = () => ({
|
|||
completionPercentage: null, // 完成比例
|
||||
planCompletionStatus: null, // 作业计划完成情况
|
||||
planChanges: '', // 计划变更及未完成情况说明
|
||||
actualHighSub: '', // 实际投入高空分包
|
||||
actualGroundSub: '', // 实际投入地面分包
|
||||
actualWorkloadList: [
|
||||
{
|
||||
workloadCategoryId: '',
|
||||
workloadCategoryName: '',
|
||||
unitPrice: '',
|
||||
settlementUnitPrice: '',
|
||||
workloadNum: '',
|
||||
},
|
||||
], // 实际完成工作内容(动态列表)
|
||||
})
|
||||
|
||||
// 检修类型表单数据结构
|
||||
|
|
@ -381,16 +396,43 @@ const onSubmit = async () => {
|
|||
|
||||
if (type === '0' || type === 0) {
|
||||
// 运行类型:拟投入/实际投入作业人员
|
||||
;(formData.value.planPersonnelList || []).forEach((item) => {
|
||||
// ;(formData.value.planPersonnelList || []).forEach((item) => {
|
||||
// proposedPersonnelList.push({
|
||||
// dayPlanId: route.query.id,
|
||||
// inspectionStationName: item.inspectionStationName,
|
||||
// personnelId: item.id,
|
||||
// name: item.name,
|
||||
// dataSource: 0, // 拟投入作业人员
|
||||
// })
|
||||
// })
|
||||
// ;(formData.value.actualPersonnelList || []).forEach((item) => {
|
||||
// proposedPersonnelList.push({
|
||||
// dayPlanId: route.query.id,
|
||||
// inspectionStationName: item.inspectionStationName,
|
||||
// personnelId: item.id,
|
||||
// name: item.name,
|
||||
// dataSource: 1, // 实际入作业人员
|
||||
// })
|
||||
// })
|
||||
formData.value.actualNationPersonnelList.forEach((item) => {
|
||||
proposedPersonnelList.push({
|
||||
dayPlanId: route.query.id,
|
||||
inspectionStationName: item.inspectionStationName,
|
||||
personnelId: item.id,
|
||||
name: item.name,
|
||||
dataSource: 0, // 拟投入作业人员
|
||||
dataSource: 1, // 实际入作业人员
|
||||
})
|
||||
})
|
||||
;(formData.value.actualPersonnelList || []).forEach((item) => {
|
||||
formData.value.actualDispatchPersonnelList.forEach((item) => {
|
||||
proposedPersonnelList.push({
|
||||
dayPlanId: route.query.id,
|
||||
inspectionStationName: item.inspectionStationName,
|
||||
personnelId: item.id,
|
||||
name: item.name,
|
||||
dataSource: 1, // 实际入作业人员
|
||||
})
|
||||
})
|
||||
formData.value.actualOverseasPersonnelList.forEach((item) => {
|
||||
proposedPersonnelList.push({
|
||||
dayPlanId: route.query.id,
|
||||
inspectionStationName: item.inspectionStationName,
|
||||
|
|
@ -454,12 +496,15 @@ const onSubmit = async () => {
|
|||
actualPersonnel,
|
||||
planPersonnel,
|
||||
actualWorkloadList,
|
||||
actualNationPersonnelList,
|
||||
actualDispatchPersonnelList,
|
||||
actualOverseasPersonnelList,
|
||||
...submitData
|
||||
} = formData.value
|
||||
|
||||
submitData.proposedPersonnelList = proposedPersonnelList
|
||||
submitData.dayPlanType = type
|
||||
if (type === '1' || type === 1) {
|
||||
if (type === '1' || type === 1 || type === '0' || type === 0) {
|
||||
submitData.workloadList = formData.value.actualWorkloadList
|
||||
}
|
||||
|
||||
|
|
@ -503,14 +548,27 @@ const personList = computed(() => {
|
|||
})
|
||||
|
||||
const filteredPersons = computed(() => {
|
||||
const list = personList.value
|
||||
if (!managerDialog.keyword) return list
|
||||
const keyword = managerDialog.keyword.toLowerCase()
|
||||
const list = personList.value || []
|
||||
const keyword = (managerDialog.keyword || '').toLowerCase().trim()
|
||||
const subType = (personSubType.value || '').toLowerCase().trim()
|
||||
|
||||
// 没有任意过滤条件时,直接返回原列表
|
||||
if (!keyword && !subType) return list
|
||||
|
||||
return list.filter((item) => {
|
||||
const name = (item.name || '').toLowerCase()
|
||||
const org = (item.org || '').toLowerCase()
|
||||
const station = (item.station || '').toLowerCase()
|
||||
return name.includes(keyword) || org.includes(keyword) || station.includes(keyword)
|
||||
const nature = (item.personnelNatureName || '').toLowerCase()
|
||||
|
||||
// 关键字匹配(为空则不过滤)
|
||||
const matchKeyword =
|
||||
!keyword || name.includes(keyword) || org.includes(keyword) || station.includes(keyword)
|
||||
|
||||
// 人员性质匹配(为空则不过滤,例如 全民 / 派遣 / 海峡)
|
||||
const matchSubType = !subType || nature.includes(subType)
|
||||
|
||||
return matchKeyword && matchSubType
|
||||
})
|
||||
})
|
||||
|
||||
|
|
@ -558,15 +616,23 @@ watch(
|
|||
},
|
||||
)
|
||||
|
||||
const onOpenPersonPicker = async (type = 'plan') => {
|
||||
const onOpenPersonPicker = async (type = 'plan', subType = null) => {
|
||||
managerDialog.type = type
|
||||
managerDialogConfig.outerVisible = true
|
||||
personSubType.value = subType
|
||||
|
||||
let currentList = []
|
||||
if (type === 'plan') {
|
||||
currentList = formData.value.planPersonnelList || []
|
||||
} else if (type === 'actual') {
|
||||
currentList = formData.value.actualPersonnelList || []
|
||||
// currentList = formData.value.actualPersonnelList || []
|
||||
if (subType === '全民') {
|
||||
currentList = formData.value.actualNationPersonnelList || []
|
||||
} else if (subType === '派遣') {
|
||||
currentList = formData.value.actualDispatchPersonnelList || []
|
||||
} else if (subType === '海峡') {
|
||||
currentList = formData.value.actualOverseasPersonnelList || []
|
||||
}
|
||||
} else if (type === 'highAltitude') {
|
||||
currentList = formData.value.highAltitudePersonnelList || []
|
||||
} else if (type === 'ground') {
|
||||
|
|
@ -620,9 +686,18 @@ const onConfirmManager = () => {
|
|||
formRef.value?.validateField?.('planPersonnelList')
|
||||
})
|
||||
} else if (type === 'actual') {
|
||||
formData.value.actualPersonnelList = [...managerDialog.selected]
|
||||
// formData.value.actualPersonnelList = [...managerDialog.selected]
|
||||
if (personSubType.value === '全民') {
|
||||
formData.value.actualNationPersonnelList = [...managerDialog.selected]
|
||||
} else if (personSubType.value === '派遣') {
|
||||
formData.value.actualDispatchPersonnelList = [...managerDialog.selected]
|
||||
} else if (personSubType.value === '海峡') {
|
||||
formData.value.actualOverseasPersonnelList = [...managerDialog.selected]
|
||||
}
|
||||
nextTick(() => {
|
||||
formRef.value?.validateField?.('actualPersonnelList')
|
||||
formRef.value?.validateField?.('actualNationPersonnelList')
|
||||
formRef.value?.validateField?.('actualDispatchPersonnelList')
|
||||
formRef.value?.validateField?.('actualOverseasPersonnelList')
|
||||
})
|
||||
} else if (type === 'highAltitude') {
|
||||
formData.value.highAltitudePersonnelList = [...managerDialog.selected]
|
||||
|
|
@ -674,28 +749,56 @@ const getDetail = async () => {
|
|||
completionPercentage: data.completionPercentage,
|
||||
planCompletionStatus: data.planCompletionStatus,
|
||||
planChanges: data.planChanges,
|
||||
actualHighSub: data.actualHighSub,
|
||||
actualGroundSub: data.actualGroundSub,
|
||||
}
|
||||
|
||||
console.log('data.proposedPersonnelList', data.proposedPersonnelList)
|
||||
|
||||
// 处理人员数据:从 proposedPersonnelList 中按照 dataSource 区分获取并重新组装
|
||||
const proposedPersonnelList = data.proposedPersonnelList || []
|
||||
|
||||
if (type === '0' || type === 0) {
|
||||
// 运行类型:使用 planPersonnelList 和 actualPersonnelList
|
||||
baseFields.planPersonnelList = proposedPersonnelList
|
||||
.filter((item) => item.dataSource === 0 || item.dataSource === '0')
|
||||
baseFields.actualWorkloadList = data.workloadList
|
||||
|
||||
formData.value.actualNationPersonnelList = proposedPersonnelList
|
||||
.filter((item) => item.personnelClassificationName.includes('全民'))
|
||||
.map((item) => ({
|
||||
id: item.personnelId,
|
||||
name: item.name || '',
|
||||
inspectionStationName: item.inspectionStationName || '',
|
||||
}))
|
||||
formData.value.actualDispatchPersonnelList = proposedPersonnelList
|
||||
.filter((item) => item.personnelClassificationName.includes('派遣'))
|
||||
.map((item) => ({
|
||||
id: item.personnelId,
|
||||
name: item.name || '',
|
||||
inspectionStationName: item.inspectionStationName || '',
|
||||
}))
|
||||
formData.value.actualOverseasPersonnelList = proposedPersonnelList
|
||||
.filter((item) => item.personnelClassificationName.includes('海峡'))
|
||||
.map((item) => ({
|
||||
id: item.personnelId,
|
||||
name: item.name || '',
|
||||
inspectionStationName: item.inspectionStationName || '',
|
||||
}))
|
||||
|
||||
baseFields.actualPersonnelList = proposedPersonnelList
|
||||
.filter((item) => item.dataSource === 1 || item.dataSource === '1')
|
||||
.map((item) => ({
|
||||
id: item.personnelId,
|
||||
name: item.name || '',
|
||||
inspectionStationName: item.inspectionStationName || '',
|
||||
}))
|
||||
// 运行类型:使用 planPersonnelList 和 actualPersonnelList
|
||||
// baseFields.planPersonnelList = proposedPersonnelList
|
||||
// .filter((item) => item.dataSource === 0 || item.dataSource === '0')
|
||||
// .map((item) => ({
|
||||
// id: item.personnelId,
|
||||
// name: item.name || '',
|
||||
// inspectionStationName: item.inspectionStationName || '',
|
||||
// }))
|
||||
|
||||
// baseFields.actualPersonnelList = proposedPersonnelList
|
||||
// .filter((item) => item.dataSource === 1 || item.dataSource === '1')
|
||||
// .map((item) => ({
|
||||
// id: item.personnelId,
|
||||
// name: item.name || '',
|
||||
// inspectionStationName: item.inspectionStationName || '',
|
||||
// }))
|
||||
} else if (type === '1' || type === 1 || type === '2' || type === 2) {
|
||||
// 检修类型和项目部类型:使用 highAltitudePersonnelList、groundPersonnelList、actualHighAltitudePersonnelList、actualGroundPersonnelList
|
||||
baseFields.highAltitudePersonnelList = proposedPersonnelList
|
||||
|
|
@ -920,10 +1023,12 @@ onMounted(() => {
|
|||
}
|
||||
|
||||
.page-footer {
|
||||
margin-top: 12px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 12px;
|
||||
position: sticky;
|
||||
bottom: 4px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.clickable-suffix {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-card shadow="never" class="card-section">
|
||||
<!-- <el-card shadow="never" class="card-section">
|
||||
<template #header>
|
||||
<div class="card-header">计划投入资源情况</div>
|
||||
</template>
|
||||
|
|
@ -222,14 +222,9 @@
|
|||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</el-card> -->
|
||||
|
||||
<el-card
|
||||
v-if="showActualCompletion"
|
||||
shadow="never"
|
||||
class="card-section"
|
||||
style="margin-top: 20px"
|
||||
>
|
||||
<el-card shadow="never" class="card-section" style="margin-top: 20px">
|
||||
<template #header>
|
||||
<div class="card-header">实际完成情况</div>
|
||||
</template>
|
||||
|
|
@ -490,7 +485,7 @@
|
|||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<div class="form-actions" v-if="!isDetail">
|
||||
<!-- <div class="form-actions" v-if="!isDetail">
|
||||
<ComButton
|
||||
v-if="!showActualCompletion"
|
||||
type="primary"
|
||||
|
|
@ -501,7 +496,7 @@
|
|||
<ComButton v-else plain type="info" @click="onCancelActualCompletion">
|
||||
取消实际完成情况
|
||||
</ComButton>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div>
|
||||
<!-- 计划投入资源情况 -->
|
||||
<el-card shadow="never" class="card-section">
|
||||
<!-- <el-card shadow="never" class="card-section">
|
||||
<template #header>
|
||||
<div class="card-header">计划投入资源情况</div>
|
||||
</template>
|
||||
|
|
@ -223,15 +223,10 @@
|
|||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</el-card> -->
|
||||
|
||||
<!-- 实际完成情况(默认隐藏) -->
|
||||
<el-card
|
||||
v-if="showActualCompletion"
|
||||
shadow="never"
|
||||
class="card-section"
|
||||
style="margin-top: 20px"
|
||||
>
|
||||
<el-card shadow="never" class="card-section" style="margin-top: 20px">
|
||||
<template #header>
|
||||
<div class="card-header">实际完成情况</div>
|
||||
</template>
|
||||
|
|
@ -546,7 +541,7 @@
|
|||
</el-card>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<div class="form-actions" v-if="!isDetail">
|
||||
<!-- <div class="form-actions" v-if="!isDetail">
|
||||
<ComButton
|
||||
v-if="!showActualCompletion"
|
||||
type="primary"
|
||||
|
|
@ -557,7 +552,7 @@
|
|||
<ComButton v-else plain type="info" @click="onCancelActualCompletion">
|
||||
取消实际完成情况
|
||||
</ComButton>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div>
|
||||
<!-- 计划投入资源情况 -->
|
||||
<el-card shadow="never" class="card-section">
|
||||
<!-- <el-card shadow="never" class="card-section">
|
||||
<template #header>
|
||||
<div class="card-header">计划投入资源情况</div>
|
||||
</template>
|
||||
|
|
@ -91,15 +91,10 @@
|
|||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</el-card> -->
|
||||
|
||||
<!-- 实际完成情况(默认隐藏) -->
|
||||
<el-card
|
||||
v-if="showActualCompletion"
|
||||
shadow="never"
|
||||
class="card-section"
|
||||
style="margin-top: 20px"
|
||||
>
|
||||
<el-card shadow="never" class="card-section" style="margin-top: 20px">
|
||||
<template #header>
|
||||
<div class="card-header">实际完成情况</div>
|
||||
</template>
|
||||
|
|
@ -114,12 +109,49 @@
|
|||
>
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="实际投入作业人员" prop="actualPersonnelList">
|
||||
<el-form-item label="实际投入全民员工" prop="actualNationPersonnelList">
|
||||
<el-input
|
||||
:model-value="selectedActualManagerNames"
|
||||
:model-value="selectedActualNationManagerNames"
|
||||
placeholder="请选择作业人员"
|
||||
readonly
|
||||
@click="onOpenActualPersonPicker"
|
||||
@click="onOpenActualPersonPicker('全民')"
|
||||
class="clickable-suffix"
|
||||
>
|
||||
<template #suffix>
|
||||
<el-icon class="clickable-suffix">
|
||||
<Search />
|
||||
</el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="12">
|
||||
<el-form-item label="实际投入派遣员工" prop="actualDispatchPersonnelList">
|
||||
<el-input
|
||||
:model-value="selectedActualDispatchManagerNames"
|
||||
placeholder="请选择作业人员"
|
||||
readonly
|
||||
@click="onOpenActualPersonPicker('派遣')"
|
||||
class="clickable-suffix"
|
||||
>
|
||||
<template #suffix>
|
||||
<el-icon class="clickable-suffix">
|
||||
<Search />
|
||||
</el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="实际投入海峡员工" prop="actualOverseasPersonnelList">
|
||||
<el-input
|
||||
:model-value="selectedActualOverseasManagerNames"
|
||||
placeholder="请选择作业人员"
|
||||
readonly
|
||||
@click="onOpenActualPersonPicker('海峡')"
|
||||
class="clickable-suffix"
|
||||
>
|
||||
<template #suffix>
|
||||
|
|
@ -186,8 +218,7 @@
|
|||
</el-row>
|
||||
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="24">
|
||||
<el-form-item label="实际完成工作内容" prop="actualWorkContent">
|
||||
<!-- <el-form-item label="实际完成工作内容" prop="actualWorkContent">
|
||||
<el-input
|
||||
:model-value="formData.actualWorkContent"
|
||||
@update:model-value="(val) => updateField('actualWorkContent', val)"
|
||||
|
|
@ -197,8 +228,88 @@
|
|||
maxlength="500"
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item> -->
|
||||
|
||||
<template v-for="(item, index) in formData.actualWorkloadList" :key="index">
|
||||
<el-col :span="8">
|
||||
<el-form-item
|
||||
:prop="`actualWorkloadList.${index}.workloadCategoryId`"
|
||||
:class="{ 'hide-required': index !== 0 }"
|
||||
>
|
||||
<template #label>
|
||||
<span v-if="index == 0">实际完成工作内容</span>
|
||||
<span v-else style="visibility: hidden">工作量</span>
|
||||
</template>
|
||||
<el-select
|
||||
clearable
|
||||
placeholder="请选择工作量类别"
|
||||
:model-value="item.workloadCategoryId"
|
||||
disabled
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-option
|
||||
v-for="option in planWorkLoadCategoryOptions"
|
||||
:key="option.workloadCategoryId"
|
||||
:value="option.workloadCategoryId"
|
||||
:label="option.workloadCategoryName"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-form-item
|
||||
label-width="0"
|
||||
:prop="`actualWorkloadList.${index}.workloadNum`"
|
||||
>
|
||||
<el-input
|
||||
clearable
|
||||
style="width: 100%"
|
||||
placeholder="输入数量"
|
||||
show-word-limit
|
||||
maxlength="7"
|
||||
disabled
|
||||
:model-value="item.workloadNum"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item
|
||||
label-width="0"
|
||||
:prop="`actualWorkloadList.${index}.actualWorkloadNum`"
|
||||
>
|
||||
<el-input
|
||||
clearable
|
||||
style="width: 100%"
|
||||
placeholder="请填写实际完成工作量"
|
||||
show-word-limit
|
||||
maxlength="7"
|
||||
:model-value="item.actualWorkloadNum"
|
||||
@update:model-value="
|
||||
(val) => updateWorkloadItem(index, 'actualWorkloadNum', val)
|
||||
"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-form-item
|
||||
label-width="0"
|
||||
:prop="`actualWorkloadList.${index}.completionRate`"
|
||||
>
|
||||
<el-input
|
||||
clearable
|
||||
disabled
|
||||
readonly
|
||||
style="width: 100%"
|
||||
:model-value="getItemCompletionPercentage(index)"
|
||||
placeholder="完成比例,自动计算"
|
||||
>
|
||||
<template #suffix>
|
||||
<span class="input-suffix">%</span>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</template>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="24">
|
||||
|
|
@ -241,6 +352,36 @@
|
|||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="实际投入高空分包" prop="actualHighSub">
|
||||
<el-input
|
||||
:model-value="formData.actualHighSub"
|
||||
@update:model-value="(val) => updateField('actualHighSub', val)"
|
||||
placeholder="请输入实际投入高空分包"
|
||||
clearable
|
||||
maxlength="7"
|
||||
show-word-limit
|
||||
>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="12">
|
||||
<el-form-item label="实际投入地面分包" prop="actualGroundSub">
|
||||
<el-input
|
||||
:model-value="formData.actualGroundSub"
|
||||
@update:model-value="(val) => updateField('actualGroundSub', val)"
|
||||
placeholder="请输入实际投入地面分包"
|
||||
clearable
|
||||
maxlength="7"
|
||||
show-word-limit
|
||||
>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="24">
|
||||
<el-form-item label="计划变更及未完成情况说明" prop="planChanges">
|
||||
|
|
@ -260,7 +401,7 @@
|
|||
</el-card>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<div class="form-actions" v-if="!isDetail">
|
||||
<!-- <div class="form-actions" v-if="!isDetail">
|
||||
<ComButton
|
||||
v-if="!showActualCompletion"
|
||||
type="primary"
|
||||
|
|
@ -271,13 +412,15 @@
|
|||
<ComButton v-else plain type="info" @click="onCancelActualCompletion">
|
||||
取消实际完成情况
|
||||
</ComButton>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="RunForm">
|
||||
import { ref, computed, nextTick, watch } from 'vue'
|
||||
import { Search } from '@element-plus/icons-vue'
|
||||
import { useOptions } from '@/hooks/useOptions'
|
||||
import { getPlanMajorListSelectAPI } from '@/api/common.js'
|
||||
import ComButton from '@/components/ComButton/index.vue'
|
||||
|
||||
const props = defineProps({
|
||||
|
|
@ -308,35 +451,41 @@ const planCompletionStatusOptions = [
|
|||
{ label: '未完成', value: '未完成' },
|
||||
]
|
||||
|
||||
// 工作量类别选项
|
||||
const { options: planWorkLoadCategoryOptions } = useOptions(
|
||||
'planWorkLoadCategoryOptions',
|
||||
getPlanMajorListSelectAPI,
|
||||
{},
|
||||
)
|
||||
|
||||
// 更新表单字段
|
||||
const updateField = (field, value) => {
|
||||
const newData = {
|
||||
...props.formData,
|
||||
[field]: value,
|
||||
}
|
||||
// 如果更新的是实际完成工作量或计划工作量,自动计算完成比例
|
||||
if (field === 'actualWorkload' || field === 'plannedWorkload') {
|
||||
// 如果更新的是实际完成工作量或实际完成工作内容列表,自动计算完成比例
|
||||
if (field === 'actualWorkload' || field === 'actualWorkloadList') {
|
||||
newData.completionPercentage = calculateCompletionPercentage(
|
||||
newData.actualWorkload,
|
||||
newData.plannedWorkload,
|
||||
newData.actualWorkloadList,
|
||||
)
|
||||
}
|
||||
emit('update:formData', newData)
|
||||
}
|
||||
|
||||
// 计算完成比例:实际完成工作量 ÷ 计划完成工作量 × 100%
|
||||
const calculateCompletionPercentage = (actualWorkload, plannedWorkload) => {
|
||||
// 计算单条工作量的完成比例:实际完成工作量 ÷ workloadNum × 100%
|
||||
const calculateItemCompletionRate = (actualWorkloadNum, workloadNum) => {
|
||||
try {
|
||||
// 转换为数字
|
||||
const actual = Number(actualWorkload)
|
||||
const planned = Number(plannedWorkload)
|
||||
const actual = Number(actualWorkloadNum)
|
||||
const planned = Number(workloadNum)
|
||||
|
||||
// 检查是否为有效数字
|
||||
if (isNaN(actual) || isNaN(planned)) {
|
||||
return null
|
||||
}
|
||||
|
||||
// 检查计划工作量是否为0或负数
|
||||
// 检查 workloadNum 是否为0或负数
|
||||
if (planned <= 0) {
|
||||
return null
|
||||
}
|
||||
|
|
@ -351,7 +500,73 @@ const calculateCompletionPercentage = (actualWorkload, plannedWorkload) => {
|
|||
const roundedPercentage = Math.round(percentage * 100) / 100
|
||||
|
||||
// 如果超过100%,限制为100%
|
||||
return roundedPercentage > 100 ? 100 : roundedPercentage
|
||||
} catch (error) {
|
||||
console.error('计算单条完成比例时出错:', error)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
// 更新工作量列表项
|
||||
const updateWorkloadItem = (index, field, value) => {
|
||||
const newWorkloadList = [...(props.formData.actualWorkloadList || [])]
|
||||
newWorkloadList[index] = {
|
||||
...newWorkloadList[index],
|
||||
[field]: value,
|
||||
}
|
||||
|
||||
// 如果更新的是 actualWorkloadNum 或 workloadNum,自动计算并更新 completionRate
|
||||
if (field === 'actualWorkloadNum' || field === 'workloadNum') {
|
||||
const item = newWorkloadList[index]
|
||||
const completionRate = calculateItemCompletionRate(item.actualWorkloadNum, item.workloadNum)
|
||||
newWorkloadList[index] = {
|
||||
...newWorkloadList[index],
|
||||
completionRate: completionRate !== null ? completionRate : null,
|
||||
}
|
||||
}
|
||||
|
||||
updateField('actualWorkloadList', newWorkloadList)
|
||||
}
|
||||
|
||||
// 获取单条工作量的完成比例(用于显示)
|
||||
const getItemCompletionPercentage = (index) => {
|
||||
const item = props.formData.actualWorkloadList?.[index]
|
||||
if (!item) return ''
|
||||
|
||||
// 如果已经有 completionRate,直接返回
|
||||
if (item.completionRate !== null && item.completionRate !== undefined) {
|
||||
return item.completionRate
|
||||
}
|
||||
|
||||
// 否则计算并返回
|
||||
const completionRate = calculateItemCompletionRate(item.actualWorkloadNum, item.workloadNum)
|
||||
return completionRate !== null ? completionRate : ''
|
||||
}
|
||||
|
||||
// 计算完成比例:实际完成工作量 ÷ 实际完成工作内容列表的长度 × 100%
|
||||
const calculateCompletionPercentage = (actualWorkload, actualWorkloadList) => {
|
||||
try {
|
||||
// 转换为数字
|
||||
const actual = Number(actualWorkload)
|
||||
|
||||
// 检查实际完成工作量是否为有效数字
|
||||
if (isNaN(actual) || actual < 0) {
|
||||
return null
|
||||
}
|
||||
|
||||
// 获取实际完成工作内容列表的长度
|
||||
const listLength = Array.isArray(actualWorkloadList) ? actualWorkloadList.length : 0
|
||||
|
||||
// 检查列表长度是否为0或负数
|
||||
if (listLength <= 0) {
|
||||
return null
|
||||
}
|
||||
|
||||
// 计算完成比例,保留2位小数
|
||||
const percentage = (actual / listLength) * 100
|
||||
const roundedPercentage = Math.round(percentage * 100) / 100
|
||||
|
||||
// 如果超过100%,限制为100%
|
||||
return roundedPercentage > 100 ? 100 : roundedPercentage
|
||||
} catch (error) {
|
||||
console.error('计算完成比例时出错:', error)
|
||||
|
|
@ -363,17 +578,16 @@ const calculateCompletionPercentage = (actualWorkload, plannedWorkload) => {
|
|||
const calculatedCompletionPercentage = computed(() => {
|
||||
const percentage = calculateCompletionPercentage(
|
||||
props.formData.actualWorkload,
|
||||
props.formData.plannedWorkload,
|
||||
props.formData.actualWorkloadList,
|
||||
)
|
||||
return percentage !== null ? percentage : ''
|
||||
})
|
||||
|
||||
// 监听实际完成工作量和计划工作量的变化,自动计算完成比例
|
||||
// 监听实际完成工作量和实际完成工作内容列表的变化,自动计算完成比例
|
||||
watch(
|
||||
() => [props.formData.actualWorkload, props.formData.plannedWorkload],
|
||||
([actualWorkload, plannedWorkload]) => {
|
||||
if (showActualCompletion.value) {
|
||||
const percentage = calculateCompletionPercentage(actualWorkload, plannedWorkload)
|
||||
() => [props.formData.actualWorkload, props.formData.actualWorkloadList],
|
||||
([actualWorkload, actualWorkloadList]) => {
|
||||
const percentage = calculateCompletionPercentage(actualWorkload, actualWorkloadList)
|
||||
if (percentage !== null && percentage !== props.formData.completionPercentage) {
|
||||
// 使用 emit 直接更新,避免循环调用
|
||||
emit('update:formData', {
|
||||
|
|
@ -381,19 +595,69 @@ watch(
|
|||
completionPercentage: percentage,
|
||||
})
|
||||
}
|
||||
},
|
||||
{ immediate: true, deep: true },
|
||||
)
|
||||
|
||||
// 监听 actualWorkloadList 的变化,自动计算每条工作量的 completionRate(主要用于数据初始化时)
|
||||
watch(
|
||||
() => props.formData.actualWorkloadList,
|
||||
(newList, oldList) => {
|
||||
if (!Array.isArray(newList) || newList.length === 0) return
|
||||
|
||||
// 检查是否有需要计算 completionRate 的项
|
||||
let needUpdate = false
|
||||
const updatedList = newList.map((item, index) => {
|
||||
// 如果 actualWorkloadNum 和 workloadNum 都存在,但 completionRate 不存在或需要更新
|
||||
if (
|
||||
item.actualWorkloadNum !== undefined &&
|
||||
item.actualWorkloadNum !== null &&
|
||||
item.workloadNum !== undefined &&
|
||||
item.workloadNum !== null
|
||||
) {
|
||||
const calculatedRate = calculateItemCompletionRate(
|
||||
item.actualWorkloadNum,
|
||||
item.workloadNum,
|
||||
)
|
||||
|
||||
// 如果计算出的值存在,且与当前值不同,则需要更新
|
||||
if (calculatedRate !== null && calculatedRate !== item.completionRate) {
|
||||
needUpdate = true
|
||||
return {
|
||||
...item,
|
||||
completionRate: calculatedRate,
|
||||
}
|
||||
}
|
||||
}
|
||||
return item
|
||||
})
|
||||
|
||||
// 只有在确实需要更新时才触发更新,避免循环
|
||||
if (needUpdate) {
|
||||
// 使用 nextTick 避免在 watch 中直接更新导致的问题
|
||||
nextTick(() => {
|
||||
emit('update:formData', {
|
||||
...props.formData,
|
||||
actualWorkloadList: updatedList,
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
{ immediate: true },
|
||||
{ immediate: true, deep: true },
|
||||
)
|
||||
|
||||
// 监听实际完成情况显示状态,显示时自动计算完成比例
|
||||
watch(
|
||||
() => showActualCompletion.value,
|
||||
(isShow) => {
|
||||
if (isShow && props.formData.actualWorkload && props.formData.plannedWorkload) {
|
||||
if (
|
||||
isShow &&
|
||||
props.formData.actualWorkload &&
|
||||
props.formData.actualWorkloadList?.length > 0
|
||||
) {
|
||||
const percentage = calculateCompletionPercentage(
|
||||
props.formData.actualWorkload,
|
||||
props.formData.plannedWorkload,
|
||||
props.formData.actualWorkloadList,
|
||||
)
|
||||
if (percentage !== null) {
|
||||
emit('update:formData', {
|
||||
|
|
@ -430,8 +694,20 @@ const rules = computed(() => ({
|
|||
}))
|
||||
|
||||
// 实际完成情况校验规则
|
||||
const actualRules = computed(() => ({
|
||||
actualPersonnelList: [{ required: true, message: '请选择实际入作业人员', trigger: 'change' }],
|
||||
const actualRules = computed(() => {
|
||||
const baseRules = {
|
||||
actualPersonnelList: [
|
||||
{ required: true, message: '请选择实际入作业人员', trigger: 'change' },
|
||||
],
|
||||
actualNationPersonnelList: [
|
||||
{ required: true, message: '请选择实际入全民员工', trigger: 'change' },
|
||||
],
|
||||
actualDispatchPersonnelList: [
|
||||
{ required: true, message: '请选择实际入派遣员工', trigger: 'change' },
|
||||
],
|
||||
actualOverseasPersonnelList: [
|
||||
{ required: true, message: '请选择实际入海峡员工', trigger: 'change' },
|
||||
],
|
||||
actualLongTimeCar: [
|
||||
{ required: true, message: '请输入实际入长租车数量', trigger: 'blur' },
|
||||
{ pattern: nonNegativeIntegerPattern, message: '请输入非负整数', trigger: 'blur' },
|
||||
|
|
@ -445,16 +721,25 @@ const actualRules = computed(() => ({
|
|||
{ required: true, message: '请输入实际完成工作量', trigger: 'blur' },
|
||||
{ pattern: nonNegativeIntegerPattern, message: '请输入非负整数', trigger: 'blur' },
|
||||
],
|
||||
|
||||
actualHighSub: [
|
||||
{ required: true, message: '请输入实际投入高空分包', trigger: 'blur' },
|
||||
{ pattern: nonNegativeIntegerPattern, message: '请输入非负整数', trigger: 'blur' },
|
||||
],
|
||||
actualGroundSub: [
|
||||
{ required: true, message: '请输入实际投入地面分包', trigger: 'blur' },
|
||||
{ pattern: nonNegativeIntegerPattern, message: '请输入非负整数', trigger: 'blur' },
|
||||
],
|
||||
completionPercentage: [
|
||||
{
|
||||
required: true,
|
||||
validator: (rule, value, callback) => {
|
||||
const percentage = calculateCompletionPercentage(
|
||||
props.formData.actualWorkload,
|
||||
props.formData.plannedWorkload,
|
||||
props.formData.actualWorkloadList,
|
||||
)
|
||||
if (percentage === null || percentage === '') {
|
||||
callback(new Error('请先填写计划工作量和实际完成工作量'))
|
||||
callback(new Error('请先填写实际完成工作内容和实际完成工作量'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
|
|
@ -465,20 +750,51 @@ const actualRules = computed(() => ({
|
|||
planCompletionStatus: [
|
||||
{ required: true, message: '请选择作业计划完成情况', trigger: 'change' },
|
||||
],
|
||||
planChanges: [{ required: false, message: '请输入计划变更及未完成情况说明', trigger: 'blur' }],
|
||||
}))
|
||||
planChanges: [
|
||||
{ required: false, message: '请输入计划变更及未完成情况说明', trigger: 'blur' },
|
||||
],
|
||||
}
|
||||
|
||||
// 为 actualWorkloadList 的每一项生成对应的校验规则
|
||||
baseRules.actualWorkloadList = (props.formData.actualWorkloadList || []).map(() => ({
|
||||
workloadCategoryId: [{ required: true, message: '请选择工作量类别', trigger: 'change' }],
|
||||
workloadNum: [
|
||||
{ required: true, message: '请输入工作量', trigger: 'blur' },
|
||||
{ pattern: nonNegativeIntegerPattern, message: '请输入非负整数', trigger: 'blur' },
|
||||
],
|
||||
actualWorkloadNum: [
|
||||
{ required: true, message: '请输入实际完成工作量', trigger: 'blur' },
|
||||
{ pattern: nonNegativeIntegerPattern, message: '请输入非负整数', trigger: 'blur' },
|
||||
],
|
||||
}))
|
||||
|
||||
return baseRules
|
||||
})
|
||||
|
||||
// 实际入作业人员名称显示
|
||||
const selectedActualManagerNames = computed(() =>
|
||||
(props.formData.actualPersonnelList || []).map((item) => item.name).join('、'),
|
||||
)
|
||||
|
||||
// 实际投入全民员工名称显示
|
||||
const selectedActualNationManagerNames = computed(() =>
|
||||
(props.formData.actualNationPersonnelList || []).map((item) => item.name).join('、'),
|
||||
)
|
||||
// 实际投入派遣员工名称显示
|
||||
const selectedActualDispatchManagerNames = computed(() =>
|
||||
(props.formData.actualDispatchPersonnelList || []).map((item) => item.name).join('、'),
|
||||
)
|
||||
// 实际投入海峡员工名称显示
|
||||
const selectedActualOverseasManagerNames = computed(() =>
|
||||
(props.formData.actualOverseasPersonnelList || []).map((item) => item.name).join('、'),
|
||||
)
|
||||
|
||||
const onOpenPersonPicker = () => {
|
||||
emit('open-person-picker', 'plan')
|
||||
}
|
||||
|
||||
const onOpenActualPersonPicker = () => {
|
||||
emit('open-person-picker', 'actual')
|
||||
const onOpenActualPersonPicker = (type) => {
|
||||
emit('open-person-picker', 'actual', type)
|
||||
}
|
||||
|
||||
// 取消实际完成情况
|
||||
|
|
@ -593,4 +909,10 @@ defineExpose({
|
|||
display: flex;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
:deep(.hide-required) {
|
||||
&.is-required .el-form-item__label::before {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@
|
|||
@click="onHandleAdd"
|
||||
v-hasPermi="['plan:dailyPlan:add']"
|
||||
>
|
||||
新增日计划
|
||||
新增日完成情况
|
||||
</ComButton>
|
||||
<ComButton
|
||||
plain
|
||||
|
|
|
|||
|
|
@ -689,7 +689,7 @@ const getInitFormData = () => ({
|
|||
workloadCategoryName: '', // 工作量类别名称
|
||||
unitPrice: '', // 单价
|
||||
workloadNum: '', // 工作量
|
||||
settlementUnitPrice: '', // 结算单价
|
||||
settlementUnitPrice: '', // 预估单价
|
||||
},
|
||||
],
|
||||
personnelArrangementList: [], // 人员排班模板 [{day: '', personnelNames: ''}]
|
||||
|
|
@ -1214,10 +1214,13 @@ onMounted(() => {
|
|||
}
|
||||
|
||||
.page-footer {
|
||||
margin-top: 12px;
|
||||
// margin-top: 12px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 12px;
|
||||
position: sticky;
|
||||
bottom: 4px;
|
||||
background-color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue