This commit is contained in:
BianLzhaoMin 2025-12-26 13:22:01 +08:00
parent ed7d25f1c0
commit 3659b0ffe3
16 changed files with 338 additions and 71 deletions

View File

@ -15,12 +15,13 @@ export default {
{
prop: 'remark',
label: '备注',
width: '200',
},
],
dialogConfig: reactive({
outerVisible: false,
outerTitle: '新业务类型',
outerTitle: '新业务类型',
outerWidth: '720px',
minHeight: '320px',
maxHeight: '80vh',

View File

@ -122,7 +122,7 @@ const actionColumns = [
//
const onHandleAdd = () => {
editId.value = null
dialogConfig.outerTitle = '新业务类型'
dialogConfig.outerTitle = '新业务类型'
dialogConfig.outerVisible = true
//
addAndEditForm.value = getInitFormData()

View File

@ -15,12 +15,13 @@ export default {
{
prop: 'remark',
label: '备注',
width: '200',
},
],
dialogConfig: reactive({
outerVisible: false,
outerTitle: '新运检站',
outerTitle: '新运检站',
outerWidth: '720px',
minHeight: '320px',
maxHeight: '80vh',

View File

@ -132,7 +132,7 @@ const actionColumns = [
//
const onHandleAdd = () => {
editId.value = null
dialogConfig.outerTitle = '新运检站'
dialogConfig.outerTitle = '新运检站'
dialogConfig.outerVisible = true
//
addAndEditForm.value = getInitFormData()

View File

@ -15,6 +15,7 @@ export default {
{
prop: 'remark',
label: '备注',
width: '200',
},
],

View File

@ -15,6 +15,7 @@ export default {
{
prop: 'remark',
label: '备注',
width: '200',
},
],

View File

@ -4,23 +4,24 @@ export default {
{
type: 'input',
prop: 'planMajorName',
placeholder: '请输入业务类型名称',
placeholder: '请输入计划类别名称',
},
],
tableColumns: [
{
prop: 'planMajorName',
label: '业务类型名称',
label: '计划类别名称',
},
{
prop: 'remark',
label: '备注',
width: '200',
},
],
dialogConfig: reactive({
outerVisible: false,
outerTitle: '新增业务类型',
outerTitle: '新建计划类别',
outerWidth: '720px',
minHeight: '320px',
maxHeight: '80vh',

View File

@ -15,6 +15,7 @@ export default {
{
prop: 'remark',
label: '备注',
width: '200',
},
],

View File

@ -15,6 +15,7 @@ export default {
{
prop: 'remark',
label: '备注',
width: '200',
},
],

View File

@ -15,6 +15,7 @@ export default {
{
prop: 'remark',
label: '备注',
width: '200',
},
],

View File

@ -20,6 +20,7 @@ export default {
{
prop: 'remark',
label: '备注',
width: '200',
},
],

View File

@ -7,7 +7,7 @@
:model="formData"
:rules="rules"
label-width="140px"
size="default"
size="large"
class="month-form"
>
<el-form-item label="月计划执行月份:" prop="month" class="month-item">
@ -47,6 +47,7 @@
@selection-change="onSelectionChange"
class="task-table"
stripe
border
:header-cell-style="{ background: '#f5f7fa', color: '#606266', fontWeight: 600 }"
>
<el-table-column type="selection" width="55" align="center" />
@ -54,8 +55,8 @@
prop="projectName"
label="项目名称"
min-width="260"
show-overflow-tooltip
align="center"
show-overflow-tooltip
/>
<el-table-column
prop="workContent"

View File

@ -12,7 +12,7 @@
ref="formRef"
:model="formData"
:rules="rules"
label-width="160"
label-width="auto"
size="large"
:disabled="isDetail"
>
@ -74,12 +74,12 @@
<el-col :span="24">
<el-form-item label="工作任务">
<el-input
type="textarea"
v-model.trim="formData.workContent"
placeholder="请输入作业内容"
disabled
maxlength="500"
show-word-limit
disabled
type="textarea"
placeholder="请输入作业内容"
v-model.trim="formData.workContent"
:autosize="{ minRows: 4, maxRows: 12 }"
/>
</el-form-item>
@ -90,15 +90,15 @@
<el-col :span="12">
<el-form-item label="类别" prop="planCategoryId">
<el-select
v-model="formData.planCategoryId"
placeholder="请选择类别"
v-model="formData.planCategoryId"
clearable
>
<el-option
v-for="item in planCategoryOptions"
:key="item.planMajorId"
:label="item.planMajorName"
:value="item.planMajorId"
:label="item.planMajorName"
v-for="item in planCategoryOptions"
/>
</el-select>
</el-form-item>
@ -110,7 +110,7 @@
<el-col :span="8">
<el-form-item
:label="index == 0 ? '工作量' : ''"
:prop="`workloadList.${index}.workloadCategoryId`"
prop="workloadCategoryId"
>
<el-select
clearable
@ -128,14 +128,13 @@
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item
label-width="0"
:prop="`workloadList.${index}.workloadNum`"
>
<el-form-item label-width="0" prop="workloadNum">
<el-input
clearable
style="width: 240px"
placeholder="输入数量"
show-word-limit
maxlength="7"
v-model="item.workloadNum"
>
<template #suffix>
@ -165,6 +164,8 @@
<el-form-item label="基塔数" prop="towerBaseNumber">
<el-input
clearable
show-word-limit
maxlength="7"
placeholder="请输入基塔数"
v-model.trim="formData.towerBaseNumber"
/>
@ -201,7 +202,21 @@
<el-row :gutter="24">
<el-col :span="12">
<el-form-item label="计划投入管理人员" prop="planPersonnelList">
<el-form-item prop="planPersonnelList">
<template #label>
<div style="display: flex; flex-direction: column">
<span>计划投入管理人员</span>
<span
style="
font-size: 12px;
color: #999;
transform: translateY(-20px);
"
>
(职工劳务派遣海峡)
</span>
</div>
</template>
<el-input
readonly
placeholder="点击选择管理人员"
@ -223,6 +238,8 @@
<el-form-item label="计划投入管理车辆数" prop="planCarNum">
<el-input
clearable
maxlength="7"
show-word-limit
placeholder="请输入车辆数量"
v-model.trim="formData.planCarNum"
/>
@ -232,10 +249,25 @@
<el-row :gutter="24">
<el-col :span="7">
<el-form-item label="计划投入熟练工人员数量" prop="planSkilledWorkerNum">
<el-form-item prop="planSkilledWorkerNum">
<template #label>
<div style="display: flex; flex-direction: column">
<span>计划投入熟练工人员数量</span>
<span
style="
font-size: 12px;
color: #999;
transform: translateY(-20px);
"
>
(分包)
</span>
</div>
</template>
<el-input
clearable
placeholder="请输入熟练工人员数量"
maxlength="7"
show-word-limit
placeholder="熟练工人员数量"
v-model.trim="formData.planSkilledWorkerNum"
/>
</el-form-item>
@ -244,20 +276,37 @@
<el-form-item
label="计划投入工日"
prop="planSkilledWorkerDay"
label-width="auto"
label-width="120"
>
<el-input
clearable
placeholder="计划投入工日"
maxlength="7"
placeholder="工日"
v-model.trim="formData.planSkilledWorkerDay"
/>
</el-form-item>
</el-col>
<el-col :span="7">
<el-form-item label="计划投入辅助工人员数量" prop="planAuxiliaryWorkerNum">
<el-form-item prop="planAuxiliaryWorkerNum">
<template #label>
<div style="display: flex; flex-direction: column">
<span>计划投入辅助工人员数量</span>
<span
style="
font-size: 12px;
color: #999;
transform: translateY(-20px);
"
>
(分包)
</span>
</div>
</template>
<el-input
clearable
placeholder="请输入辅助工人员数量"
maxlength="7"
show-word-limit
placeholder="辅助工人员数量"
v-model.trim="formData.planAuxiliaryWorkerNum"
/>
</el-form-item>
@ -266,11 +315,13 @@
<el-form-item
label="计划投入工日"
prop="planAuxiliaryWorkerDay"
label-width="auto"
label-width="120"
>
<el-input
clearable
placeholder="计划投入工日"
maxlength="7"
show-word-limit
placeholder="工日"
v-model.trim="formData.planAuxiliaryWorkerDay"
/>
</el-form-item>
@ -282,6 +333,8 @@
<el-form-item label="计划投入分包车辆数" prop="planSubCarNum">
<el-input
clearable
maxlength="7"
show-word-limit
placeholder="请输入分包车辆数量"
v-model.trim="formData.planSubCarNum"
/>
@ -291,6 +344,8 @@
<el-form-item label="实际工作天数">
<el-input
clearable
maxlength="7"
show-word-limit
placeholder="请输入实际工作天数"
v-model.trim="formData.actualWorkingDay"
/>
@ -635,25 +690,46 @@ const rules = {
businessTypeId: [{ required: true, message: '请选择业务类型', trigger: 'change' }],
riskLevel: [{ required: true, message: '请选择风险等级', trigger: 'change' }],
planCategoryId: [{ required: true, message: '请选择类别', trigger: 'change' }],
towerBaseNumber: [{ required: true, message: '请输入基塔数', trigger: 'blur' }],
towerBaseNumber: [
{ required: true, message: '请输入基塔数', trigger: 'blur' },
{ pattern: /^[1-9]\d*$/, message: '请输入正整数', trigger: 'blur' },
],
planPersonnelList: [{ required: true, message: '请选择计划投入管理人员', trigger: 'blur' }],
workloadCategoryId: [{ required: true, message: '请选择工作量类别', trigger: 'change' }],
workloadNum: [
{ required: true, message: '请输入工作量', trigger: 'blur' },
{ pattern: /^[1-9]\d*$/, message: '请输入正整数', trigger: 'blur' },
],
planCarNum: [{ required: true, message: '请输入计划投入管理人员车辆数', trigger: 'blur' }],
planCarNum: [
{ required: true, message: '请输入管理人员车辆数', trigger: 'blur' },
{ pattern: /^[1-9]\d*$/, message: '请输入正整数', trigger: 'blur' },
],
planSkilledWorkerNum: [
{ required: true, message: '请输入计划投入熟练工人员数量', trigger: 'blur' },
{ required: true, message: '请输入熟练工人员数量', trigger: 'blur' },
{ pattern: /^[1-9]\d*$/, message: '请输入正整数', trigger: 'blur' },
],
planAuxiliaryWorkerNum: [
{ required: true, message: '请输入计划投入辅助工人员数量', trigger: 'blur' },
{ required: true, message: '请输入辅助工人员数量', trigger: 'blur' },
{ pattern: /^[1-9]\d*$/, message: '请输入正整数', trigger: 'blur' },
],
planSkilledWorkerDay: [
{ required: true, message: '请输入计划投入熟练工人员工日', trigger: 'blur' },
{ required: true, message: '请输入工日', trigger: 'blur' },
{ pattern: /^[1-9]\d*$/, message: '请输入正整数', trigger: 'blur' },
],
planAuxiliaryWorkerDay: [
{ required: true, message: '请输入计划投入辅助工人员工日', trigger: 'blur' },
{ required: true, message: '请输入工日', trigger: 'blur' },
{ pattern: /^[1-9]\d*$/, message: '请输入正整数', trigger: 'blur' },
],
planSubCarNum: [
{ required: true, message: '请输入分包车辆数', trigger: 'blur' },
{ pattern: /^[1-9]\d*$/, message: '请输入正整数', trigger: 'blur' },
],
actualWorkingDay: [
{ required: true, message: '请输入实际工作天数', trigger: 'blur' },
{ pattern: /^[1-9]\d*$/, message: '请输入正整数', trigger: 'blur' },
],
planSubCarNum: [{ required: true, message: '请输入计划投入分包车辆数', trigger: 'blur' }],
actualWorkingDay: [{ required: true, message: '请输入实际工作天数', trigger: 'blur' }],
}
const onBack = () => {

View File

@ -235,11 +235,6 @@ const onExportPersonArrange = (queryParams) => {
...queryParams,
},
`人员安排表.xlsx`,
{
headers: {
'Content-Type': 'application/json',
},
},
)
}
@ -251,11 +246,6 @@ const onExportOverallSummary = (queryParams) => {
...queryParams,
},
`整体汇总表.xlsx`,
{
headers: {
'Content-Type': 'application/json',
},
},
)
}
@ -267,11 +257,6 @@ const onExportWorkloadSummary = (queryParams) => {
...queryParams,
},
`工作量汇总表.xlsx`,
{
headers: {
'Content-Type': 'application/json',
},
},
)
}
</script>

View File

@ -10,11 +10,12 @@
<!-- 月份 -->
<el-form-item label="月份" prop="planManagementMonth">
<el-date-picker
v-model="formData.planManagementMonth"
type="month"
style="width: 100%"
value-format="YYYY-MM"
placeholder="请选择月份"
style="width: 100%"
v-model="formData.planManagementMonth"
@change="handleMonthChange"
/>
</el-form-item>
@ -22,7 +23,7 @@
<el-form-item label="项目名称" prop="projectName">
<el-input
clearable
maxlength="50"
maxlength="100"
show-word-limit
placeholder="请输入项目名称"
v-model.trim="formData.projectName"
@ -35,9 +36,9 @@
type="textarea"
maxlength="500"
show-word-limit
:autosize="{ minRows: 3, maxRows: 6 }"
placeholder="请输入作业内容"
v-model.trim="formData.workContent"
:autosize="{ minRows: 4, maxRows: 8 }"
/>
</el-form-item>
@ -64,20 +65,28 @@
<el-date-picker
v-model="formData.stareDate"
type="date"
value-format="YYYY-MM-DD"
placeholder="请选择计划开始时间"
style="width: 100%"
value-format="YYYY-MM-DD"
:placeholder="!formData.planManagementMonth ? '请先选择月份' : '请选择计划开始时间'"
:disabled="!formData.planManagementMonth"
:disabled-date="disabledStartDate"
:default-value="defaultDateValue"
@change="handleStartDateChange"
/>
</el-form-item>
<!-- 计划结束时间 -->
<el-form-item label="计划结束时间" prop="endDate">
<el-date-picker
v-model="formData.endDate"
type="date"
value-format="YYYY-MM-DD"
placeholder="请选择计划结束时间"
style="width: 100%"
v-model="formData.endDate"
value-format="YYYY-MM-DD"
:placeholder="!formData.planManagementMonth ? '请先选择月份' : '请选择计划结束时间'"
:disabled="!formData.planManagementMonth"
:disabled-date="disabledEndDate"
:default-value="defaultDateValue"
@change="handleEndDateChange"
/>
</el-form-item>
@ -104,7 +113,7 @@
type="textarea"
maxlength="200"
show-word-limit
:autosize="{ minRows: 3, maxRows: 6 }"
:autosize="{ minRows: 4, maxRows: 8 }"
placeholder="请输入备注"
v-model.trim="formData.remark"
/>
@ -113,7 +122,7 @@
</template>
<script setup name="AddAndEditForm">
import { ref } from 'vue'
import { ref, watch, computed } from 'vue'
const { proxy } = getCurrentInstance()
const { plan_risk_level } = proxy.useDict('plan_risk_level')
@ -130,13 +139,186 @@ const props = defineProps({
const formRef = ref(null)
//
const monthRange = computed(() => {
if (!props.formData.planManagementMonth) {
return { start: null, end: null }
}
const [year, month] = props.formData.planManagementMonth.split('-')
const start = new Date(year, parseInt(month) - 1, 1)
const end = new Date(year, parseInt(month), 0, 23, 59, 59) //
return {
start: start.getTime(),
end: end.getTime(),
}
})
//
const defaultDateValue = computed(() => {
if (!props.formData.planManagementMonth) {
return new Date() // 使
}
const [year, month] = props.formData.planManagementMonth.split('-')
//
return new Date(year, parseInt(month) - 1, 1)
})
//
const isDateInMonth = (dateStr) => {
if (!dateStr || !monthRange.value.start) return false
const date = new Date(dateStr)
const timestamp = date.getTime()
return timestamp >= monthRange.value.start && timestamp <= monthRange.value.end
}
//
const handleMonthChange = (value) => {
// value YYYY-MM
if (!value) {
//
props.formData.stareDate = ''
props.formData.endDate = ''
formRef.value?.clearValidate(['stareDate', 'endDate'])
return
}
//
const [year, month] = value.split('-')
const monthStart = new Date(year, parseInt(month) - 1, 1).getTime()
const monthEnd = new Date(year, parseInt(month), 0, 23, 59, 59).getTime()
//
if (props.formData.stareDate) {
const stareTimestamp = new Date(props.formData.stareDate).getTime()
if (stareTimestamp < monthStart || stareTimestamp > monthEnd) {
props.formData.stareDate = ''
formRef.value?.clearValidate('stareDate')
}
}
//
if (props.formData.endDate) {
const endTimestamp = new Date(props.formData.endDate).getTime()
if (endTimestamp < monthStart || endTimestamp > monthEnd) {
props.formData.endDate = ''
formRef.value?.clearValidate('endDate')
}
}
}
//
const disabledStartDate = (time) => {
if (!monthRange.value.start || !monthRange.value.end) {
return true
}
const timestamp = time.getTime()
return timestamp < monthRange.value.start || timestamp > monthRange.value.end
}
//
const disabledEndDate = (time) => {
if (!monthRange.value.start || !monthRange.value.end) {
return true
}
const timestamp = time.getTime()
//
if (timestamp < monthRange.value.start || timestamp > monthRange.value.end) {
return true
}
//
if (props.formData.stareDate) {
const startTimestamp = new Date(props.formData.stareDate).getTime()
return timestamp < startTimestamp
}
return false
}
//
const handleStartDateChange = (value) => {
//
if (value && props.formData.endDate) {
const startTimestamp = new Date(value).getTime()
const endTimestamp = new Date(props.formData.endDate).getTime()
if (endTimestamp < startTimestamp) {
props.formData.endDate = ''
formRef.value?.clearValidate('endDate')
}
}
}
//
const handleEndDateChange = (value) => {
//
if (value && props.formData.stareDate) {
const startTimestamp = new Date(props.formData.stareDate).getTime()
const endTimestamp = new Date(value).getTime()
if (endTimestamp < startTimestamp) {
proxy.$modal.msgError('结束时间不能早于开始时间')
props.formData.endDate = ''
formRef.value?.clearValidate('endDate')
}
}
}
const rules = {
planManagementMonth: [{ required: true, message: '请选择月份', trigger: 'change' }],
projectName: [{ required: true, message: '请输入项目名称', trigger: 'blur' }],
workContent: [{ required: true, message: '请输入作业内容', trigger: 'blur' }],
inspectionStationId: [{ required: true, message: '请选择实施部门', trigger: 'change' }],
stareDate: [{ required: true, message: '请选择计划开始时间', trigger: 'change' }],
endDate: [{ required: true, message: '请选择计划结束时间', trigger: 'change' }],
stareDate: [
{ required: true, message: '请选择计划开始时间', trigger: 'change' },
{
validator: (rule, value, callback) => {
if (!value) {
callback()
return
}
if (!props.formData.planManagementMonth) {
callback(new Error('请先选择月份'))
return
}
if (!isDateInMonth(value)) {
callback(new Error('开始时间必须在选定的月份内'))
return
}
callback()
},
trigger: 'change',
},
],
endDate: [
{ required: true, message: '请选择计划结束时间', trigger: 'change' },
{
validator: (rule, value, callback) => {
if (!value) {
callback()
return
}
if (!props.formData.planManagementMonth) {
callback(new Error('请先选择月份'))
return
}
if (!isDateInMonth(value)) {
callback(new Error('结束时间必须在选定的月份内'))
return
}
if (props.formData.stareDate) {
const startTimestamp = new Date(props.formData.stareDate).getTime()
const endTimestamp = new Date(value).getTime()
if (endTimestamp < startTimestamp) {
callback(new Error('结束时间不能早于开始时间'))
return
}
}
callback()
},
trigger: 'change',
},
],
riskLevel: [{ required: true, message: '请选择风险等级', trigger: 'change' }],
}

View File

@ -41,7 +41,9 @@ import { ref, nextTick, getCurrentInstance, computed } from 'vue'
import { listPlanAPI, addPlanAPI, updatePlanAPI, delPlanAPI } from '@/api/planMange/plan.js'
import { getInspectionStationSelectAPI } from '@/api/common.js'
import { useOptions } from '@/hooks/useOptions'
import useDictStore from '@/store/modules/dict'
import { selectDictLabel } from '@/utils/ruoyi'
import dayjs from 'dayjs'
import config from './config'
import ComTable from '@/components/ComTable/index.vue'
import ComButton from '@/components/ComButton/index.vue'
@ -50,6 +52,7 @@ import AddAndEditForm from './addAndEditForm.vue'
const { tableColumns: baseTableColumns, dialogConfig, buildFormColumns } = config
const { proxy } = getCurrentInstance()
const dictStore = useDictStore()
const formRef = ref(null)
const comTableRef = ref(null)
@ -63,13 +66,24 @@ const formColumns = computed(() =>
buildFormColumns(inspectionStationOptions.value, plan_risk_level.value),
)
// formatter store
const createDynamicDictFormatter = (dictType, fieldName = null) => {
return (row, column, cellValue) => {
const value = fieldName ? row[fieldName] : cellValue
// store
const dictData = dictStore.getDict(dictType) || []
return selectDictLabel(dictData, value)
}
}
// formatter
const tableColumns = computed(() => {
return baseTableColumns.map((column) => {
if (column.prop === 'riskLevel') {
return {
...column,
formatter: proxy.createDictFormatter(plan_risk_level.value, 'riskLevel'),
// 使 formatter
formatter: createDynamicDictFormatter('plan_risk_level', 'riskLevel'),
}
}
return column
@ -87,7 +101,7 @@ console.log(inspectionStationOptions, 'inspectionStationOptions')
// 1.
const getInitFormData = () => ({
planManagementMonth: '', //
planManagementMonth: dayjs().format('YYYY-MM'), //
projectName: '', //
workContent: '', //
inspectionStationId: null, //