|
|
@@ -3,87 +3,60 @@
|
|
|
<header class="safety-platform-container__header">
|
|
|
<div class="breadcrumb-title">
|
|
|
<BreadcrumbBack />
|
|
|
- {{ pageTitle }}
|
|
|
+ 查看施工安全申请
|
|
|
</div>
|
|
|
</header>
|
|
|
<main class="safety-platform-container__main">
|
|
|
- <el-form ref="formRef" :inline="true" label-width="auto" :model="formValue" :rules="rules" :disabled="isView">
|
|
|
- <el-form-item label="项目名称" prop="projectName">
|
|
|
- <el-input v-model="formValue.projectName" size="large" placeholder="请输入项目名称" style="width: 330px" />
|
|
|
+ <el-form ref="formRef" :inline="true" label-width="auto" :model="formValue" :disabled="true">
|
|
|
+ <el-form-item label="项目名称">
|
|
|
+ <el-input v-model="formValue.projectName" size="large" style="width: 330px" />
|
|
|
</el-form-item>
|
|
|
|
|
|
- <el-form-item label="施工单位" prop="constructionUnit">
|
|
|
- <el-input
|
|
|
- v-model="formValue.constructionUnit"
|
|
|
- size="large"
|
|
|
- placeholder="请输入单位全称"
|
|
|
- style="width: 330px"
|
|
|
- />
|
|
|
+ <el-form-item label="施工单位">
|
|
|
+ <el-input v-model="formValue.constructionUnit" size="large" style="width: 330px" />
|
|
|
</el-form-item>
|
|
|
|
|
|
- <el-form-item label="施工地点" prop="constructionLocation">
|
|
|
- <el-input
|
|
|
- v-model="formValue.constructionLocation"
|
|
|
- size="large"
|
|
|
- placeholder="楼宇名称/区域"
|
|
|
- style="width: 330px"
|
|
|
- />
|
|
|
+ <el-form-item label="施工地点">
|
|
|
+ <el-input v-model="formValue.constructionLocation" size="large" style="width: 330px" />
|
|
|
</el-form-item>
|
|
|
|
|
|
- <el-form-item label="施工人数" prop="workerCount">
|
|
|
- <el-input-number v-model="formValue.workerCount" size="large" :min="1" style="width: 330px" />
|
|
|
+ <el-form-item label="施工人数">
|
|
|
+ <el-input-number v-model="formValue.workerCount" size="large" style="width: 330px" />
|
|
|
</el-form-item>
|
|
|
|
|
|
- <el-form-item label="项目负责人" prop="projectManagerName">
|
|
|
- <el-input v-model="formValue.projectManagerName" size="large" placeholder="负责人姓名" style="width: 330px" />
|
|
|
+ <el-form-item label="项目负责人">
|
|
|
+ <el-input v-model="formValue.projectManagerName" size="large" style="width: 330px" />
|
|
|
</el-form-item>
|
|
|
|
|
|
- <el-form-item label="负责人电话1" prop="projectManagerPhone1">
|
|
|
- <el-input v-model="formValue.projectManagerPhone1" size="large" placeholder="必填" style="width: 330px" />
|
|
|
+ <el-form-item label="负责人电话1">
|
|
|
+ <el-input v-model="formValue.projectManagerPhone1" size="large" style="width: 330px" />
|
|
|
</el-form-item>
|
|
|
|
|
|
- <el-form-item label="负责人电话2" prop="projectManagerPhone2">
|
|
|
- <el-input v-model="formValue.projectManagerPhone2" size="large" placeholder="选填" style="width: 330px" />
|
|
|
+ <el-form-item label="负责人电话2">
|
|
|
+ <el-input v-model="formValue.projectManagerPhone2" size="large" style="width: 330px" />
|
|
|
</el-form-item>
|
|
|
|
|
|
- <el-form-item label="现场安全员" prop="siteSafetyManagerName">
|
|
|
- <el-input
|
|
|
- v-model="formValue.siteSafetyManagerName"
|
|
|
- size="large"
|
|
|
- placeholder="安全员姓名"
|
|
|
- style="width: 330px"
|
|
|
- />
|
|
|
+ <el-form-item label="现场安全员">
|
|
|
+ <el-input v-model="formValue.siteSafetyManagerName" size="large" style="width: 330px" />
|
|
|
</el-form-item>
|
|
|
|
|
|
- <el-form-item label="安全员电话1" prop="siteSafetyPhone1">
|
|
|
- <el-input v-model="formValue.siteSafetyPhone1" size="large" placeholder="必填" style="width: 330px" />
|
|
|
+ <el-form-item label="安全员电话1">
|
|
|
+ <el-input v-model="formValue.siteSafetyPhone1" size="large" style="width: 330px" />
|
|
|
</el-form-item>
|
|
|
|
|
|
- <el-form-item label="安全员电话2" prop="siteSafetyPhone2">
|
|
|
- <el-input v-model="formValue.siteSafetyPhone2" size="large" placeholder="选填" style="width: 330px" />
|
|
|
+ <el-form-item label="安全员电话2">
|
|
|
+ <el-input v-model="formValue.siteSafetyPhone2" size="large" style="width: 330px" />
|
|
|
</el-form-item>
|
|
|
|
|
|
- <el-form-item label="开始时间" prop="projectStartTime">
|
|
|
- <el-date-picker
|
|
|
- v-model="formValue.projectStartTime"
|
|
|
- type="date"
|
|
|
- value-format="YYYY-MM-DD"
|
|
|
- size="large"
|
|
|
- style="width: 330px"
|
|
|
- />
|
|
|
+ <el-form-item label="开始时间">
|
|
|
+ <el-date-picker v-model="formValue.projectStartTime" type="date" size="large" style="width: 330px" />
|
|
|
</el-form-item>
|
|
|
|
|
|
- <el-form-item label="结束时间" prop="projectEndTime">
|
|
|
- <el-date-picker
|
|
|
- v-model="formValue.projectEndTime"
|
|
|
- type="date"
|
|
|
- value-format="YYYY-MM-DD"
|
|
|
- size="large"
|
|
|
- style="width: 330px"
|
|
|
- />
|
|
|
+ <el-form-item label="结束时间">
|
|
|
+ <el-date-picker v-model="formValue.projectEndTime" type="date" size="large" style="width: 330px" />
|
|
|
</el-form-item>
|
|
|
|
|
|
- <el-form-item label="涉及工种" prop="involvedTrades" style="width: 87.2%">
|
|
|
+ <el-form-item label="涉及工种" style="width: 87.2%">
|
|
|
<el-checkbox-group v-model="tradeArray">
|
|
|
<el-checkbox
|
|
|
v-for="t in ['水电', '泥瓦', '木工', '焊接', '气割', '登高', '密闭', '特种驾驶', '其他']"
|
|
|
@@ -93,83 +66,52 @@
|
|
|
</el-checkbox-group>
|
|
|
</el-form-item>
|
|
|
|
|
|
- <el-form-item v-if="tradeArray.includes('其他')" label="其他工种说明" prop="otherTrade">
|
|
|
- <el-input v-model="formValue.otherTrade" size="large" placeholder="请补充工种类型" style="width: 330px" />
|
|
|
+ <el-form-item v-if="tradeArray.includes('其他')" label="其他工种说明" style="width: 330px">
|
|
|
+ <el-input v-model="formValue.otherTrade" size="large" />
|
|
|
</el-form-item>
|
|
|
|
|
|
- <el-form-item label="施工内容简述" prop="constructionContent" style="width: 87.2%">
|
|
|
- <el-input
|
|
|
- type="textarea"
|
|
|
- v-model="formValue.constructionContent"
|
|
|
- size="large"
|
|
|
- :rows="3"
|
|
|
- placeholder="简要描述施工方案"
|
|
|
- />
|
|
|
+ <el-form-item label="施工内容简述" style="width: 87.2%">
|
|
|
+ <el-input type="textarea" v-model="formValue.constructionContent" size="large" :rows="3" />
|
|
|
</el-form-item>
|
|
|
|
|
|
- <el-form-item label="备注说明" prop="otherDescription" style="width: 87.2%">
|
|
|
- <el-input
|
|
|
- type="textarea"
|
|
|
- v-model="formValue.otherDescription"
|
|
|
- size="large"
|
|
|
- :rows="3"
|
|
|
- placeholder="其他补充说明"
|
|
|
- />
|
|
|
+ <el-form-item label="备注说明" style="width: 87.2%">
|
|
|
+ <el-input type="textarea" v-model="formValue.otherDescription" size="large" :rows="3" />
|
|
|
</el-form-item>
|
|
|
|
|
|
<div style="width: 100%; height: 1px; background: #eee; margin: 20px 0"></div>
|
|
|
- <div style="width: 100%; margin-bottom: 20px; font-weight: bold; padding-left: 10px">附件清单(全项必填)</div>
|
|
|
+ <div style="width: 100%; margin-bottom: 20px; font-weight: bold; padding-left: 10px">附件清单</div>
|
|
|
|
|
|
- <el-form-item
|
|
|
- v-for="item in attachmentConfigs"
|
|
|
- :key="item.prop"
|
|
|
- :label="item.label"
|
|
|
- :prop="item.prop"
|
|
|
- style="width: 43.6%"
|
|
|
- >
|
|
|
- <UploadFiles
|
|
|
- :disabled="isView"
|
|
|
- @upload-success="(fileList) => handleUploadSuccess(item.prop, fileList)"
|
|
|
- :fileList="attachmentLists[item.prop]"
|
|
|
- />
|
|
|
+ <el-form-item v-for="item in attachmentConfigs" :key="item.prop" :label="item.label" style="width: 43.6%">
|
|
|
+ <UploadFiles label="上传附件" :disabled="true" :fileList="attachmentLists[item.prop]" />
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <div style="width: 100%; height: 1px; background: #eee; margin: 20px 0"></div>
|
|
|
+ <el-form-item label="审批流程" style="width: 87.2%">
|
|
|
+ <el-select v-model="formValue.templateId" size="large" style="width: 330px">
|
|
|
+ <el-option v-for="opt in approvalOptions" :key="opt.id" :label="opt.templateName" :value="opt.id" />
|
|
|
+ </el-select>
|
|
|
</el-form-item>
|
|
|
</el-form>
|
|
|
</main>
|
|
|
<footer class="safety-platform-container__footer">
|
|
|
<el-button @click="router.back()">返回</el-button>
|
|
|
- <el-button v-if="!isView" type="primary" :loading="submiting" @click="handleSubmit">保存</el-button>
|
|
|
</footer>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script lang="ts" setup>
|
|
|
- import { ref, reactive, watch, onMounted, computed } from 'vue';
|
|
|
+ import { ref, reactive, onMounted } from 'vue';
|
|
|
import { useRouter, useRoute } from 'vue-router';
|
|
|
- import { ElMessage } from 'element-plus';
|
|
|
- import dayjs from 'dayjs';
|
|
|
import UploadFiles from '@/components/UploadFiles/UploadFiles.vue';
|
|
|
- import {
|
|
|
- constructionSafetySaveConstruction,
|
|
|
- constructionSafetyQueryDetailConstruction,
|
|
|
- } from '@/api/production-safety/responsibility-implementation';
|
|
|
- import { unformatAttachment, formatAttachmentList } from '@/components/UploadFiles/utils';
|
|
|
+ import { getAllApproval } from '@/api/approval/approval';
|
|
|
+ import { constructionSafetyQueryDetailConstruction } from '@/api/production-safety/responsibility-implementation';
|
|
|
+ import { unformatAttachment } from '@/components/UploadFiles/utils';
|
|
|
|
|
|
const router = useRouter();
|
|
|
const route = useRoute();
|
|
|
- const formRef = ref<any>(null);
|
|
|
- const submiting = ref(false);
|
|
|
const tradeArray = ref<string[]>([]);
|
|
|
+ const approvalOptions = ref<any[]>([]);
|
|
|
|
|
|
- // 页面模式逻辑
|
|
|
- const pageType = computed(() => route.query.type as string); // 'view', 'edit', 'add'
|
|
|
- const businessId = computed(() => route.query.id as string);
|
|
|
- const isView = computed(() => pageType.value === 'view');
|
|
|
- const pageTitle = computed(() => {
|
|
|
- if (isView.value) return '查看施工安全申请';
|
|
|
- return businessId.value ? '编辑施工安全申请' : '新增施工安全申请';
|
|
|
- });
|
|
|
-
|
|
|
- // 附件项定义
|
|
|
const attachmentConfigs = [
|
|
|
{ label: '施工安全交底', prop: 'safetyCommitmentAttachment' },
|
|
|
{ label: '安全管理协议', prop: 'safetyAgreementAttachment' },
|
|
|
@@ -185,10 +127,9 @@
|
|
|
{ label: '特种设备合格证', prop: 'specialEquipmentCertAttachment' },
|
|
|
];
|
|
|
|
|
|
- // 响应式数据
|
|
|
const attachmentLists = reactive<any>(Object.fromEntries(attachmentConfigs.map((a) => [a.prop, []])));
|
|
|
+
|
|
|
const formValue = reactive<any>({
|
|
|
- id: undefined,
|
|
|
projectName: '',
|
|
|
constructionContent: '',
|
|
|
constructionLocation: '',
|
|
|
@@ -205,92 +146,44 @@
|
|
|
involvedTrades: '',
|
|
|
otherTrade: '',
|
|
|
otherDescription: '',
|
|
|
- ...Object.fromEntries(attachmentConfigs.map((a) => [a.prop, ''])),
|
|
|
+ templateId: '',
|
|
|
});
|
|
|
|
|
|
- // 详情回显逻辑
|
|
|
- const initDetail = async () => {
|
|
|
- if (!businessId.value) return;
|
|
|
+ const initData = async () => {
|
|
|
+ const id = route.query.id as string;
|
|
|
+ if (!id) return;
|
|
|
+
|
|
|
try {
|
|
|
- const res = await constructionSafetyQueryDetailConstruction(route.query.id);
|
|
|
- if (res?.data) {
|
|
|
- Object.assign(formValue, res.data);
|
|
|
- // 处理多选框回显
|
|
|
- tradeArray.value = res.data.involvedTrades ? res.data.involvedTrades.split(',') : [];
|
|
|
- // 处理附件回显
|
|
|
+ // 1. 获取审批流选项(为了回显 label)
|
|
|
+ const approvals = await getAllApproval();
|
|
|
+ approvalOptions.value = approvals || [];
|
|
|
+
|
|
|
+ // 2. 获取详情
|
|
|
+ const res = await constructionSafetyQueryDetailConstruction(id);
|
|
|
+ if (res) {
|
|
|
+ // 基础数据回显
|
|
|
+ Object.assign(formValue, res);
|
|
|
+
|
|
|
+ // 工种回显
|
|
|
+ if (res.involvedTrades) {
|
|
|
+ tradeArray.value = res.involvedTrades.split(',');
|
|
|
+ }
|
|
|
+
|
|
|
+ // 附件回显还原
|
|
|
attachmentConfigs.forEach((item) => {
|
|
|
- if (res.data[item.prop]) {
|
|
|
- attachmentLists[item.prop] = unformatAttachment(res.data[item.prop]);
|
|
|
+ if (res[item.prop]) {
|
|
|
+ attachmentLists[item.prop] = unformatAttachment(res[item.prop]);
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
} catch (error) {
|
|
|
- console.error('Detail fetch error:', error);
|
|
|
+ console.error('获取详情数据失败:', error);
|
|
|
}
|
|
|
};
|
|
|
|
|
|
- onMounted(initDetail);
|
|
|
-
|
|
|
- // 附件变更处理
|
|
|
- const handleUploadSuccess = async (prop: string, fileList: any[]) => {
|
|
|
- attachmentLists[prop] = fileList;
|
|
|
- // 直接转成 JSON 字符串存入表单对象,确保提交时格式正确
|
|
|
- const formatted = await formatAttachmentList(fileList);
|
|
|
- formValue[prop] = formatted && formatted.length > 0 ? JSON.stringify(formatted) : '';
|
|
|
- formRef.value?.validateField(prop);
|
|
|
- };
|
|
|
-
|
|
|
- // 监听工种
|
|
|
- watch(tradeArray, (val) => {
|
|
|
- formValue.involvedTrades = val.join(',');
|
|
|
+ onMounted(() => {
|
|
|
+ initData();
|
|
|
});
|
|
|
-
|
|
|
- // 校验规则
|
|
|
- const rules = reactive({
|
|
|
- projectName: [{ required: true, message: '请输入项目名称', trigger: 'blur' }],
|
|
|
- constructionUnit: [{ required: true, message: '请输入施工单位', trigger: 'blur' }],
|
|
|
- constructionLocation: [{ required: true, message: '请输入施工地点', trigger: 'blur' }],
|
|
|
- workerCount: [{ required: true, message: '请输入人数', trigger: 'blur' }],
|
|
|
- projectManagerName: [{ required: true, message: '请输入项目负责人', trigger: 'blur' }],
|
|
|
- projectManagerPhone1: [{ required: true, message: '请输入联系电话', trigger: 'blur' }],
|
|
|
- siteSafetyManagerName: [{ required: true, message: '请输入安全负责人', trigger: 'blur' }],
|
|
|
- siteSafetyPhone1: [{ required: true, message: '请输入联系电话', trigger: 'blur' }],
|
|
|
- projectStartTime: [{ required: true, message: '请选择开始时间', trigger: 'change' }],
|
|
|
- projectEndTime: [
|
|
|
- { required: true, message: '请选择结束时间', trigger: 'change' },
|
|
|
- {
|
|
|
- validator: (_rule, value, callback) => {
|
|
|
- if (value && formValue.projectStartTime && dayjs(value).isBefore(dayjs(formValue.projectStartTime))) {
|
|
|
- callback(new Error('不能早于开始时间'));
|
|
|
- } else {
|
|
|
- callback();
|
|
|
- }
|
|
|
- },
|
|
|
- trigger: 'change',
|
|
|
- },
|
|
|
- ],
|
|
|
- involvedTrades: [{ required: true, message: '请选择工种', trigger: 'change' }],
|
|
|
- constructionContent: [{ required: true, message: '请输入简述', trigger: 'blur' }],
|
|
|
- ...Object.fromEntries(
|
|
|
- attachmentConfigs.map((a) => [a.prop, [{ required: true, message: `请上传${a.label}`, trigger: 'change' }]]),
|
|
|
- ),
|
|
|
- });
|
|
|
-
|
|
|
- const handleSubmit = () => {
|
|
|
- formRef.value?.validate((valid: boolean) => {
|
|
|
- if (valid) {
|
|
|
- submiting.value = true;
|
|
|
- constructionSafetySaveConstruction(formValue)
|
|
|
- .then(() => {
|
|
|
- ElMessage.success('保存成功!');
|
|
|
- router.push({ name: 'constructionSafetyManage' });
|
|
|
- })
|
|
|
- .finally(() => {
|
|
|
- submiting.value = false;
|
|
|
- });
|
|
|
- }
|
|
|
- });
|
|
|
- };
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
@@ -302,17 +195,17 @@
|
|
|
padding: 24px;
|
|
|
background-color: #fff;
|
|
|
}
|
|
|
-
|
|
|
- // 深度调整封装组件在 inline 模式下的表现
|
|
|
:deep(.el-form-item) {
|
|
|
margin-right: 20px;
|
|
|
margin-bottom: 24px;
|
|
|
vertical-align: top;
|
|
|
-
|
|
|
- // 让附件标签宽度更有呼吸感
|
|
|
.el-form-item__label {
|
|
|
font-weight: bold;
|
|
|
}
|
|
|
}
|
|
|
+ // :deep(.el-input.is-disabled .el-input__wrapper) {
|
|
|
+ // background-color: #f8f9fb;
|
|
|
+ // color: #606266;
|
|
|
+ // }
|
|
|
}
|
|
|
</style>
|