view.vue 65 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346
  1. <template>
  2. <div class="safety-platform-container">
  3. <header class="safety-platform-container__header">
  4. <div class="breadcrumb-title"><BreadcrumbBack /> 查看危险作业申请</div>
  5. </header>
  6. <!-- <main class="safety-platform-container__main">
  7. <el-form ref="formRef" :model="formValue" :rules="rules" disabled label-width="160px" label-position="right">
  8. <div class="section-title">基础信息</div>
  9. <div class="form-grid">
  10. <el-form-item label="审批流程" prop="templateId" class="span-full">
  11. <el-select v-model="formValue.templateId" placeholder="请选择审批流程" size="large" clearable>
  12. <el-option v-for="opt in approvalOptions" :key="opt.id" :label="opt.templateName" :value="opt.id" />
  13. </el-select>
  14. </el-form-item>
  15. <el-form-item label="作业类型" prop="hazardOperationType">
  16. <el-select disabled size="large" v-model="formValue.hazardOperationType" class="w-100">
  17. <el-option :value="1" label="有限空间作业" />
  18. <el-option :value="2" label="高处作业" />
  19. <el-option :value="3" label="临时用电" />
  20. <el-option :value="4" label="动火作业" />
  21. </el-select>
  22. </el-form-item>
  23. <el-form-item label="申请单位" prop="applicationUnitName"
  24. ><el-input size="large" v-model="formValue.applicationUnitName"
  25. /></el-form-item>
  26. <el-form-item label="申请人" prop="applicantName"
  27. ><el-input size="large" v-model="formValue.applicantName"
  28. /></el-form-item>
  29. <el-form-item label="申请部门" prop="applicationDepartment"
  30. ><el-cascader
  31. v-model="formValue.applicationDepartmentId"
  32. size="large"
  33. ref="cascaderRef"
  34. :options="firstLevelDepts"
  35. :props="cascaderProp"
  36. :show-all-levels="false"
  37. placeholder="请选择部门名称"
  38. filterable
  39. @change="handleChangeDept"
  40. style="width: 100%"
  41. /></el-form-item>
  42. <el-form-item label="联系电话" prop="applicantPhone"
  43. ><el-input size="large" v-model="formValue.applicantPhone"
  44. /></el-form-item>
  45. <el-form-item label="备注信息" prop="remark" class="span-full">
  46. <el-input size="large" v-model="formValue.remark" type="textarea" :rows="2" placeholder="备注信息..." />
  47. </el-form-item>
  48. </div>
  49. <div class="form-line-divider"></div>
  50. <template v-if="formValue.hazardOperationType === 1">
  51. <div class="section-title">有限空间作业详情</div>
  52. <div class="form-grid">
  53. <el-form-item label="所属单位" prop="space.confinedSpaceUnit"
  54. ><el-input size="large" v-model="formValue.space.confinedSpaceUnit"
  55. /></el-form-item>
  56. <el-form-item label="空间名称" prop="space.confinedSpaceName"
  57. ><el-input size="large" v-model="formValue.space.confinedSpaceName"
  58. /></el-form-item>
  59. <el-form-item label="负责人" prop="space.unitResponsible"
  60. ><el-input size="large" v-model="formValue.space.unitResponsible"
  61. /></el-form-item>
  62. <el-form-item label="监护人" prop="space.supervisor"
  63. ><el-input size="large" v-model="formValue.space.supervisor"
  64. /></el-form-item>
  65. <el-form-item label="作业人" prop="space.operator"
  66. ><el-input size="large" v-model="formValue.space.operator" placeholder="多人请用逗号分隔"
  67. /></el-form-item>
  68. <el-form-item label="其他作业" prop="space.otherSpecialOps"
  69. ><el-input size="large" v-model="formValue.space.otherSpecialOps"
  70. /></el-form-item>
  71. <el-form-item label="开始时间" prop="space.operationStartTime"
  72. ><el-date-picker
  73. size="large"
  74. v-model="formValue.space.operationStartTime"
  75. value-format="YYYY-MM-DD"
  76. class="w-100"
  77. /></el-form-item>
  78. <el-form-item label="结束时间" prop="space.operationEndTime"
  79. ><el-date-picker
  80. size="large"
  81. v-model="formValue.space.operationEndTime"
  82. value-format="YYYY-MM-DD"
  83. class="w-100"
  84. /></el-form-item>
  85. </div>
  86. <div class="sub-group-box">
  87. <div class="sub-label is-required-manual section-title-flex">环境当前浓度指标 (初始评估)</div>
  88. <el-table :data="[formValue.space]" border class="density-table" style="margin-bottom: 20px">
  89. <el-table-column label="有毒有害物质 (toxicHazardous)">
  90. <template #default="scope">
  91. <el-form-item prop="space.toxicHazardous" :rules="r" label-width="0" class="m-0"
  92. ><el-input v-model="scope.row.toxicHazardous"
  93. /></el-form-item>
  94. </template>
  95. </el-table-column>
  96. <el-table-column label="可燃气 (flammable)">
  97. <template #default="scope">
  98. <el-form-item prop="space.flammable" :rules="r" label-width="0" class="m-0"
  99. ><el-input v-model="scope.row.flammable"
  100. /></el-form-item>
  101. </template>
  102. </el-table-column>
  103. <el-table-column label="氧含量 (oxygenContent)">
  104. <template #default="scope">
  105. <el-form-item prop="space.oxygenContent" :rules="r" label-width="0" class="m-0"
  106. ><el-input v-model="scope.row.oxygenContent"
  107. /></el-form-item>
  108. </template>
  109. </el-table-column>
  110. </el-table>
  111. </div>
  112. <div class="form-grid mt-20">
  113. <el-form-item label="作业内容" prop="space.operationContent" class="span-full"
  114. ><el-input size="large" v-model="formValue.space.operationContent" type="textarea"
  115. /></el-form-item>
  116. <el-form-item label="危害辨识" prop="space.hazardIdentification" class="span-full"
  117. ><el-input size="large" v-model="formValue.space.hazardIdentification" type="textarea"
  118. /></el-form-item>
  119. <el-form-item label="作业附件" class="span-full"
  120. ><UploadFiles
  121. label="上传附件"
  122. disabled
  123. @upload-success="(l) => handleUpload('space', 'attachment', l)"
  124. :fileList="listMap['space.attachment']"
  125. /></el-form-item>
  126. </div>
  127. </template>
  128. <template v-else-if="formValue.hazardOperationType === 2">
  129. <div class="section-title">高处作业详情</div>
  130. <div class="form-grid">
  131. <el-form-item label="作业地点" prop="highAltitude.operationLocation"
  132. ><el-input size="large" v-model="formValue.highAltitude.operationLocation"
  133. /></el-form-item>
  134. <el-form-item label="作业单位" prop="highAltitude.operationUnit"
  135. ><el-input size="large" v-model="formValue.highAltitude.operationUnit"
  136. /></el-form-item>
  137. <el-form-item label="作业高度(m)" prop="highAltitude.operationHeight"
  138. ><el-input-number
  139. size="large"
  140. v-model="formValue.highAltitude.operationHeight"
  141. class="w-100"
  142. :controls="false"
  143. /></el-form-item>
  144. <el-form-item label="作业类别" prop="highAltitude.operationType"
  145. ><el-input size="large" v-model="formValue.highAltitude.operationType" placeholder="如:悬挂作业"
  146. /></el-form-item>
  147. <el-form-item label="作业人姓名" prop="highAltitude.operatorName"
  148. ><el-input size="large" v-model="formValue.highAltitude.operatorName"
  149. /></el-form-item>
  150. <el-form-item label="监护人" prop="highAltitude.supervisor"
  151. ><el-input size="large" v-model="formValue.highAltitude.supervisor"
  152. /></el-form-item>
  153. <el-form-item label="开始时间" prop="highAltitude.operationStartTime"
  154. ><el-date-picker
  155. size="large"
  156. v-model="formValue.highAltitude.operationStartTime"
  157. value-format="YYYY-MM-DD"
  158. class="w-100"
  159. /></el-form-item>
  160. <el-form-item label="结束时间" prop="highAltitude.operationEndTime"
  161. ><el-date-picker
  162. size="large"
  163. v-model="formValue.highAltitude.operationEndTime"
  164. value-format="YYYY-MM-DD"
  165. class="w-100"
  166. /></el-form-item>
  167. <el-form-item label="作业内容" prop="highAltitude.operationContent" class="span-full"
  168. ><el-input size="large" v-model="formValue.highAltitude.operationContent" type="textarea"
  169. /></el-form-item>
  170. <el-form-item label="危害辨识" prop="highAltitude.hazardIdentification" class="span-full"
  171. ><el-input size="large" v-model="formValue.highAltitude.hazardIdentification" type="textarea"
  172. /></el-form-item>
  173. <el-form-item label="作业附件" class="span-full"
  174. ><UploadFiles
  175. label="上传附件"
  176. disabled
  177. @upload-success="(l) => handleUpload('highAltitude', 'attachment', l)"
  178. :fileList="listMap['highAltitude.attachment']"
  179. /></el-form-item>
  180. </div>
  181. </template>
  182. <template v-else-if="formValue.hazardOperationType === 3">
  183. <div class="section-title">临时用电详情</div>
  184. <div class="form-grid">
  185. <el-form-item label="需求部门" prop="electricityList.requestDepartment"
  186. ><el-input size="large" v-model="formValue.electricityList.requestDepartment"
  187. /></el-form-item>
  188. <el-form-item label="用电类型" prop="electricityList.electricityType">
  189. <el-select v-model="formValue.electricityList.electricityType" class="w-100">
  190. <el-option :value="1" label="长期" /><el-option :value="2" label="临时" />
  191. </el-select>
  192. </el-form-item>
  193. <el-form-item label="责任人" prop="electricityList.contactPerson"
  194. ><el-input size="large" v-model="formValue.electricityList.contactPerson"
  195. /></el-form-item>
  196. <el-form-item label="设备功率" prop="electricityList.equipmentPower"
  197. ><el-input size="large" v-model="formValue.electricityList.equipmentPower"
  198. /></el-form-item>
  199. <el-form-item label="开始时间" prop="electricityList.operationStartTime"
  200. ><el-date-picker
  201. size="large"
  202. v-model="formValue.electricityList.operationStartTime"
  203. value-format="YYYY-MM-DD"
  204. class="w-100"
  205. /></el-form-item>
  206. <el-form-item label="结束时间" prop="electricityList.operationEndTime"
  207. ><el-date-picker
  208. size="large"
  209. v-model="formValue.electricityList.operationEndTime"
  210. value-format="YYYY-MM-DD"
  211. class="w-100"
  212. /></el-form-item>
  213. <el-form-item label="保护措施" prop="electricityList.safety" class="span-full"
  214. ><el-input size="large" v-model="formValue.electricityList.safety"
  215. /></el-form-item>
  216. <el-form-item label="用电事由" prop="electricityList.reason" class="span-full"
  217. ><el-input size="large" v-model="formValue.electricityList.reason" type="textarea"
  218. /></el-form-item>
  219. <el-form-item label="申请附件" class="span-full"
  220. ><UploadFiles
  221. label="上传附件"
  222. disabled
  223. @upload-success="(l) => handleUpload('electricityList', 'attachment', l)"
  224. :fileList="listMap['electricityList.attachment']"
  225. /></el-form-item>
  226. </div>
  227. </template>
  228. <template v-else-if="formValue.hazardOperationType === 4">
  229. <div class="section-title">动火作业详情</div>
  230. <div class="sub-label">A. 动火任务信息</div>
  231. <div class="form-grid">
  232. <el-form-item label="动火地点" prop="hot.hotWorkLocation"
  233. ><el-input size="large" v-model="formValue.hot.hotWorkLocation"
  234. /></el-form-item>
  235. <el-form-item label="动火级别" prop="hot.hotWorkLevel">
  236. <el-select v-model="formValue.hot.hotWorkLevel" class="w-100">
  237. <el-option :value="1" label="一级" /><el-option :value="2" label="二级" /><el-option
  238. :value="3"
  239. label="三级"
  240. />
  241. </el-select>
  242. </el-form-item>
  243. <el-form-item label="特殊时段" prop="hot.isSpecialPeriod">
  244. <el-radio-group v-model="formValue.hot.isSpecialPeriod">
  245. <el-radio :label="1">是 (节假日/重大活动)</el-radio>
  246. <el-radio :label="0">否</el-radio>
  247. </el-radio-group>
  248. </el-form-item>
  249. <el-form-item label="动火类型" prop="hot.hotWorkType"
  250. ><el-input size="large" v-model="formValue.hot.hotWorkType" placeholder="气焊/电焊/打磨等"
  251. /></el-form-item>
  252. <el-form-item label="开始时间" prop="hot.hotWorkStart"
  253. ><el-date-picker
  254. size="large"
  255. v-model="formValue.hot.hotWorkStart"
  256. value-format="YYYY-MM-DD"
  257. class="w-100"
  258. /></el-form-item>
  259. <el-form-item label="结束时间" prop="hot.hotWorkEnd"
  260. ><el-date-picker size="large" v-model="formValue.hot.hotWorkEnd" value-format="YYYY-MM-DD" class="w-100"
  261. /></el-form-item>
  262. <el-form-item label="动火任务" prop="hot.hotWorkTask" class="span-full"
  263. ><el-input size="large" v-model="formValue.hot.hotWorkTask" type="textarea"
  264. /></el-form-item>
  265. <el-form-item label="危险性分析" prop="hot.hazardAnalysis" class="span-full"
  266. ><el-input size="large" v-model="formValue.hot.hazardAnalysis" type="textarea"
  267. /></el-form-item>
  268. </div>
  269. <div class="sub-label">B. 责任人信息</div>
  270. <div class="form-grid">
  271. <el-form-item label="动火作业人员" prop="hot.hotWorkman"
  272. ><el-input size="large" v-model="formValue.hot.hotWorkman"
  273. /></el-form-item>
  274. <el-form-item label="动火人电话" prop="hot.hotWorkContact"
  275. ><el-input size="large" v-model="formValue.hot.hotWorkContact"
  276. /></el-form-item>
  277. <el-form-item label="施工单位监护人" prop="hot.constructionSupervisor"
  278. ><el-input size="large" v-model="formValue.hot.constructionSupervisor"
  279. /></el-form-item>
  280. <el-form-item label="监护人电话" prop="hot.supervisorContact"
  281. ><el-input size="large" v-model="formValue.hot.supervisorContact"
  282. /></el-form-item>
  283. <el-form-item label="现场负责人" prop="hot.constructionSiteLeader"
  284. ><el-input size="large" v-model="formValue.hot.constructionSiteLeader"
  285. /></el-form-item>
  286. <el-form-item label="教育人" prop="hot.constructionEducator"
  287. ><el-input size="large" v-model="formValue.hot.constructionEducator"
  288. /></el-form-item>
  289. <el-form-item label="申请部门监护人" prop="hot.hotWorkSupervisor"
  290. ><el-input size="large" v-model="formValue.hot.hotWorkSupervisor"
  291. /></el-form-item>
  292. <el-form-item label="部门监护电话" prop="hot.supervisorNumber"
  293. ><el-input size="large" v-model="formValue.hot.supervisorNumber"
  294. /></el-form-item>
  295. </div>
  296. <div class="sub-label">C. 防护措施与附件</div>
  297. <div class="form-grid">
  298. <el-form-item label="安全防护措施" prop="hot.fireSafetyMeasures" class="span-full"
  299. ><el-input size="large" v-model="formValue.hot.fireSafetyMeasures" type="textarea"
  300. /></el-form-item>
  301. <el-form-item label="现场检查情况" prop="hot.supervisorMeasures" class="span-full"
  302. ><el-input size="large" v-model="formValue.hot.supervisorMeasures" type="textarea"
  303. /></el-form-item>
  304. <el-form-item label="动火现场照片"
  305. ><UploadFiles
  306. disabled
  307. label="上传附件"
  308. @upload-success="(l) => handleUpload('hot', 'photos', l)"
  309. :fileList="listMap['hot.photos']"
  310. /></el-form-item>
  311. <el-form-item label="身份证复印件"
  312. ><UploadFiles
  313. disabled
  314. label="上传附件"
  315. @upload-success="(l) => handleUpload('hot', 'idCard', l)"
  316. :fileList="listMap['hot.idCard']"
  317. /></el-form-item>
  318. <el-form-item label="特种作业证"
  319. ><UploadFiles
  320. disabled
  321. label="上传附件"
  322. @upload-success="(l) => handleUpload('hot', 'optionCard', l)"
  323. :fileList="listMap['hot.optionCard']"
  324. /></el-form-item>
  325. <el-form-item label="安全教育记录"
  326. ><UploadFiles
  327. disabled
  328. label="上传附件"
  329. @upload-success="(l) => handleUpload('hot', 'safetyEducationPlan', l)"
  330. :fileList="listMap['hot.safetyEducationPlan']"
  331. /></el-form-item>
  332. <el-form-item label="施工方案"
  333. ><UploadFiles
  334. disabled
  335. label="上传附件"
  336. @upload-success="(l) => handleUpload('hot', 'constructionPlan', l)"
  337. :fileList="listMap['hot.constructionPlan']"
  338. /></el-form-item>
  339. <el-form-item label="准备工作照片"
  340. ><UploadFiles
  341. disabled
  342. label="上传附件"
  343. @upload-success="(l) => handleUpload('hot', 'preparationPhotos', l)"
  344. :fileList="listMap['hot.preparationPhotos']"
  345. /></el-form-item>
  346. <el-form-item label="管理协议"
  347. ><UploadFiles
  348. disabled
  349. label="上传附件"
  350. @upload-success="(l) => handleUpload('hot', 'safetyManagementAgreement', l)"
  351. :fileList="listMap['hot.safetyManagementAgreement']"
  352. /></el-form-item>
  353. </div>
  354. </template>
  355. <div class="form-line-divider"></div>
  356. <div class="section-title-flex">
  357. <span class="is-required-manual">安全措施清单</span>
  358. <el-button type="primary" @click="addRow('measure')">+ 新增措施</el-button>
  359. </div>
  360. <el-table :data="formValue.measure" border class="mb-20">
  361. <el-table-column label="序号" prop="serialNumber" width="100" align="center" />
  362. <el-table-column label="措施内容"
  363. ><template #default="scope"><el-input v-model="scope.row.safetyMeasure" /></template
  364. ></el-table-column>
  365. <el-table-column label="确认人" width="200"
  366. ><template #default="scope"><el-input v-model="scope.row.confirmer" /></template
  367. ></el-table-column>
  368. <el-table-column label="操作" width="80" align="center">
  369. <template #default="scope"
  370. ><el-button type="primary" link @click="removeRow('measure', scope.$index)">删除</el-button></template
  371. >
  372. </el-table-column>
  373. </el-table>
  374. <div class="section-title-flex">
  375. <span class="is-required-manual">危害分析记录</span>
  376. <el-button type="primary" @click="addRow('analysis')">+ 新增记录</el-button>
  377. </div>
  378. <el-table :data="formValue.analysis" border>
  379. <el-table-column label="检测部位"
  380. ><template #default="scope"><el-input v-model="scope.row.analysisPosition" /></template
  381. ></el-table-column>
  382. <el-table-column label="有毒物质及浓度"
  383. ><template #default="scope"><el-input v-model="scope.row.toxicSubstance" /></template
  384. ></el-table-column>
  385. <el-table-column label="可燃气及浓度"
  386. ><template #default="scope"><el-input v-model="scope.row.flammableGas" /></template
  387. ></el-table-column>
  388. <el-table-column label="氧含量"
  389. ><template #default="scope"><el-input v-model="scope.row.oxygenContent" /></template
  390. ></el-table-column>
  391. <el-table-column label="检测人" width="130"
  392. ><template #default="scope"><el-input v-model="scope.row.analyst" /></template
  393. ></el-table-column>
  394. <el-table-column label="检测时间" width="220"
  395. ><template #default="scope">
  396. <el-date-picker
  397. v-model="scope.row.analysisTime"
  398. value-format="YYYY-MM-DD"
  399. style="width: 100%"
  400. /> </template
  401. ></el-table-column>
  402. <el-table-column label="操作" width="80" align="center">
  403. <template #default="scope"
  404. ><el-button type="primary" link @click="removeRow('analysis', scope.$index)">删除</el-button></template
  405. >
  406. </el-table-column>
  407. </el-table>
  408. </el-form>
  409. </main> -->
  410. <main class="safety-platform-container__main">
  411. <el-form ref="formRef" :model="formValue" :rules="rules" disabled label-width="180px" label-position="right">
  412. <div class="section-title">基础信息</div>
  413. <div class="form-grid" style="width:50%">
  414. <el-form-item label="申请单位" prop="applicationUnitName"
  415. ><el-input size="large" placeholder="输入申请单位名称" v-model="formValue.applicationUnitName"
  416. /></el-form-item>
  417. <el-form-item label="申请人" prop="applicantName"
  418. ><el-input size="large" placeholder="输入申请人" v-model="formValue.applicantName"
  419. /></el-form-item>
  420. <el-form-item label="申请部门" prop="applicationDepartment"
  421. ><el-cascader
  422. v-model="formValue.applicationDepartmentId"
  423. size="large"
  424. ref="cascaderRef"
  425. :options="firstLevelDepts"
  426. :props="cascaderProp"
  427. :show-all-levels="false"
  428. placeholder="请选择申请部门"
  429. filterable
  430. @change="handleChangeDept"
  431. style="width: 100%"
  432. /></el-form-item>
  433. <el-form-item label="申请人电话" prop="applicantPhone"
  434. ><el-input size="large" placeholder="输入申请人电话" v-model="formValue.applicantPhone"
  435. /></el-form-item>
  436. <el-form-item label="危险作业类别" prop="hazardOperationType">
  437. <el-select size="large" v-model="formValue.hazardOperationType" placeholder="选择危险作业类别">
  438. <el-option :value="1" label="有限空间" />
  439. <el-option :value="2" label="高处作业" />
  440. <el-option :value="3" label="临时用电" />
  441. <el-option :value="4" label="动火作业" />
  442. </el-select>
  443. </el-form-item>
  444. <el-form-item label="审批流程" prop="templateId" class="span-full">
  445. <el-select v-model="formValue.templateId" placeholder="请选择审批流程" size="large" clearable>
  446. <el-option v-for="opt in approvalOptions" :key="opt.id" :label="opt.templateName" :value="opt.id" />
  447. </el-select>
  448. </el-form-item>
  449. <!-- <el-form-item label="备注信息" prop="remark" class="span-full">
  450. <el-input size="large" v-model="formValue.remark" type="textarea" :rows="2" placeholder="备注信息..." />
  451. </el-form-item> -->
  452. </div>
  453. <div class="form-line-divider"></div>
  454. <template v-if="formValue.hazardOperationType === 1">
  455. <div class="section-title">有限空间作业详情</div>
  456. <div class="form-grid" style="width:50%">
  457. <el-form-item label="有限空间所属单位" prop="space.confinedSpaceUnit"
  458. ><el-input size="large" placeholder="输入有限空间所属单位" v-model="formValue.space.confinedSpaceUnit"
  459. /></el-form-item>
  460. <el-form-item label="有限空间名称" prop="space.confinedSpaceName"
  461. ><el-input size="large" placeholder="输入有限空间名称" v-model="formValue.space.confinedSpaceName"
  462. /></el-form-item>
  463. <el-form-item label="作业内容" prop="space.operationContent" class="span-full"
  464. ><el-input size="large" placeholder="输入作业内容" v-model="formValue.space.operationContent" type="textarea"
  465. /></el-form-item>
  466. <el-form-item label="作业开始时间" prop="space.operationStartTime"
  467. ><el-date-picker
  468. size="large"
  469. v-model="formValue.space.operationStartTime"
  470. value-format="YYYY-MM-DD"
  471. placeholder="作业开始时间"
  472. style="width: 100%"
  473. /></el-form-item>
  474. <el-form-item label="作业结束时间" prop="space.operationEndTime"
  475. ><el-date-picker
  476. size="large"
  477. v-model="formValue.space.operationEndTime"
  478. placeholder="作业结束时间"
  479. value-format="YYYY-MM-DD"
  480. style="width: 100%"
  481. /></el-form-item>
  482. <el-form-item label="作业单位负责人" prop="space.unitResponsible"
  483. ><el-input size="large" placeholder="输入作业单位负责人" v-model="formValue.space.unitResponsible"
  484. /></el-form-item>
  485. <el-form-item label="监护人" prop="space.supervisor"
  486. ><el-input size="large" placeholder="输入监护人" v-model="formValue.space.supervisor"
  487. /></el-form-item>
  488. <el-form-item label="作业人" prop="space.operator"
  489. ><el-input size="large" placeholder="输入作业人" v-model="formValue.space.operator"
  490. /></el-form-item>
  491. <el-form-item label="涉及其它特殊作业" prop="space.otherSpecialOps"
  492. ><el-input size="large" placeholder="输入涉及其它特殊作业" v-model="formValue.space.otherSpecialOps"
  493. /></el-form-item>
  494. <el-form-item label="危害辨识" prop="space.hazardIdentification" class="span-full"
  495. ><el-input size="large" placeholder="输入危害辨识" v-model="formValue.space.hazardIdentification" type="textarea"
  496. /></el-form-item>
  497. <el-form-item label="作业附件" class="span-full" prop="space.attachment">
  498. <!-- <UploadFiles
  499. label="上传附件"
  500. disabled
  501. @upload-success="(l) => handleUpload('space', 'attachment', l)"
  502. :fileList="listMap['space.attachment']"
  503. /> -->
  504. <div class="file-list" v-if="listMap['space.attachment'].length > 0">
  505. <div v-for="file in listMap['space.attachment']" :key="file.fileId" class="file-item">
  506. <div class="file-info">
  507. <img :src="FILE_TYPE_ICON[file.fileType as keyof typeof FILE_TYPE_ICON]" />
  508. <span class="file-name">{{ file.fileName }}</span>
  509. </div>
  510. <div link class="fileAction" @click="previewOnline(file.fileUrl, file.fileType as keyof typeof FILE_TYPE_ICON)">预览</div>
  511. <div link class="fileAction" @click.stop="downloadFile(file.fileUrl, file.fileName)">下载</div>
  512. </div>
  513. </div>
  514. </el-form-item>
  515. </div>
  516. <div class="sub-group-box">
  517. <div class="sub-label is-required-manual section-title-flex">项目分析-物质分析标准</div>
  518. <el-table :data="[formValue.space]" border class="density-table" style="margin-bottom: 20px">
  519. <el-table-column label="有毒有害介质">
  520. <template #default="scope">
  521. <el-form-item prop="space.toxicHazardous" :rules="r" label-width="0" class="m-0"
  522. ><el-input v-model="scope.row.toxicHazardous"
  523. /></el-form-item>
  524. </template>
  525. </el-table-column>
  526. <el-table-column label="可燃气">
  527. <template #default="scope">
  528. <el-form-item prop="space.flammable" :rules="r" label-width="0" class="m-0"
  529. ><el-input v-model="scope.row.flammable"
  530. /></el-form-item>
  531. </template>
  532. </el-table-column>
  533. <el-table-column label="氧含量">
  534. <template #default="scope">
  535. <el-form-item prop="space.oxygenContent" :rules="r" label-width="0" class="m-0"
  536. ><el-input v-model="scope.row.oxygenContent"
  537. /></el-form-item>
  538. </template>
  539. </el-table-column>
  540. </el-table>
  541. </div>
  542. <div class="section-title-flex">
  543. <span class="is-required-manual">项目分析-危害分析记录</span>
  544. <el-button type="primary" @click="addRow('analysis')">+ 新增记录</el-button>
  545. </div>
  546. <el-table :data="formValue.analysis" border>
  547. <el-table-column label="有毒有害介质"
  548. ><template #default="scope"><el-input v-model="scope.row.toxicSubstance" /></template
  549. ></el-table-column>
  550. <el-table-column label="可燃气"
  551. ><template #default="scope"><el-input v-model="scope.row.flammableGas" /></template
  552. ></el-table-column>
  553. <el-table-column label="氧含量"
  554. ><template #default="scope"><el-input v-model="scope.row.oxygenContent" /></template
  555. ></el-table-column>
  556. <el-table-column label="部位"
  557. ><template #default="scope"><el-input v-model="scope.row.analysisPosition" /></template
  558. ></el-table-column>
  559. <el-table-column label="分析人" width="130"
  560. ><template #default="scope"><el-input v-model="scope.row.analyst" /></template
  561. ></el-table-column>
  562. <el-table-column label="时间" width="220"
  563. ><template #default="scope">
  564. <el-date-picker
  565. v-model="scope.row.analysisTime"
  566. value-format="YYYY-MM-DD"
  567. style="width: 100%"
  568. /> </template
  569. ></el-table-column>
  570. <el-table-column label="操作" width="100" align="center">
  571. <template #default="scope"
  572. ><el-button type="primary" link @click="removeRow('analysis', scope.$index)">删除</el-button></template
  573. >
  574. </el-table-column>
  575. </el-table>
  576. </template>
  577. <template v-else-if="formValue.hazardOperationType === 2">
  578. <div class="section-title">高处作业详情</div>
  579. <div class="form-grid" style="width:50%">
  580. <el-form-item label="作业地点" prop="highAltitude.operationLocation"
  581. ><el-input size="large" placeholder="输入作业地点" v-model="formValue.highAltitude.operationLocation"
  582. /></el-form-item>
  583. <el-form-item label="作业开始时间" prop="highAltitude.operationStartTime"
  584. ><el-date-picker
  585. size="large"
  586. v-model="formValue.highAltitude.operationStartTime"
  587. value-format="YYYY-MM-DD"
  588. placeholder="作业开始时间"
  589. style="width:100%"
  590. /></el-form-item>
  591. <el-form-item label="作业结束时间" prop="highAltitude.operationEndTime"
  592. ><el-date-picker
  593. size="large"
  594. v-model="formValue.highAltitude.operationEndTime"
  595. value-format="YYYY-MM-DD"
  596. placeholder="作业结束时间"
  597. style="width:100%"
  598. /></el-form-item>
  599. <el-form-item label="作业内容" prop="highAltitude.operationContent" class="span-full"
  600. ><el-input size="large" placeholder="输入作业内容" v-model="formValue.highAltitude.operationContent" type="textarea"
  601. /></el-form-item>
  602. <el-form-item label="作业高度" prop="highAltitude.operationHeight"
  603. ><el-input-number
  604. size="large"
  605. placeholder="输入作业高度"
  606. v-model="formValue.highAltitude.operationHeight"
  607. style="width:100%"
  608. :controls="false"
  609. /></el-form-item>
  610. <el-form-item label="作业单位" prop="highAltitude.operationUnit"
  611. ><el-input size="large" placeholder="输入作业单位" v-model="formValue.highAltitude.operationUnit"
  612. /></el-form-item>
  613. <el-form-item label="作业类别" prop="highAltitude.operationType"
  614. ><el-input size="large" v-model="formValue.highAltitude.operationType" placeholder="输入作业类别"
  615. /></el-form-item>
  616. <el-form-item label="作业人" prop="highAltitude.operatorName"
  617. ><el-input size="large" placeholder="输入作业人" v-model="formValue.highAltitude.operatorName"
  618. /></el-form-item>
  619. <el-form-item label="监护人" prop="highAltitude.supervisor"
  620. ><el-input size="large" placeholder="输入监护人" v-model="formValue.highAltitude.supervisor"
  621. /></el-form-item>
  622. <el-form-item label="涉及其它特殊作业" prop="highAltitude.operatorJob"
  623. ><el-input size="large" placeholder="输入涉及其它特殊作业" v-model="formValue.highAltitude.operatorJob"
  624. /></el-form-item>
  625. <el-form-item label="危害辨识" prop="highAltitude.hazardIdentification" class="span-full"
  626. ><el-input size="large" placeholder="输入危害辨识" v-model="formValue.highAltitude.hazardIdentification" type="textarea"
  627. /></el-form-item>
  628. <el-form-item label="作业附件" class="span-full" prop="highAltitude.attachment">
  629. <!-- <UploadFiles
  630. label="上传附件"
  631. @upload-success="(l) => handleUpload('highAltitude', 'attachment', l)"
  632. :fileList="listMap['highAltitude.attachment']"
  633. /> -->
  634. <div class="file-list" v-if="listMap['highAltitude.attachment'].length > 0">
  635. <div v-for="file in listMap['highAltitude.attachment']" :key="file.fileId" class="file-item">
  636. <div class="file-info">
  637. <img :src="FILE_TYPE_ICON[file.fileType as keyof typeof FILE_TYPE_ICON]" />
  638. <span class="file-name">{{ file.fileName }}</span>
  639. </div>
  640. <div link class="fileAction" @click="previewOnline(file.fileUrl, file.fileType as keyof typeof FILE_TYPE_ICON)">预览</div>
  641. <div link class="fileAction" @click.stop="downloadFile(file.fileUrl, file.fileName)">下载</div>
  642. </div>
  643. </div>
  644. </el-form-item>
  645. </div>
  646. </template>
  647. <template v-else-if="formValue.hazardOperationType === 3">
  648. <div class="section-title">临时用电详情</div>
  649. <div class="form-grid" style="width:50%">
  650. <el-form-item label="需求部门/IPT团队" prop="electricityList.requestDepartment"
  651. ><el-input size="large" placeholder="输入需求部门/IPT团队" v-model="formValue.electricityList.requestDepartment"
  652. /></el-form-item>
  653. <el-form-item label="接用电性质" prop="electricityList.electricityType">
  654. <el-select v-model="formValue.electricityList.electricityType" class="w-100">
  655. <el-option :value="1" label="长期" />
  656. <el-option :value="2" label="临时" />
  657. </el-select>
  658. </el-form-item>
  659. <el-form-item label="作业开始时间" prop="electricityList.operationStartTime"
  660. ><el-date-picker
  661. size="large"
  662. placeholder="作业开始时间"
  663. v-model="formValue.electricityList.operationStartTime"
  664. value-format="YYYY-MM-DD"
  665. class="w-100"
  666. style="width: 100%;"
  667. /></el-form-item>
  668. <el-form-item label="作业结束时间" prop="electricityList.operationEndTime"
  669. ><el-date-picker
  670. size="large"
  671. placeholder="作业结束时间"
  672. v-model="formValue.electricityList.operationEndTime"
  673. value-format="YYYY-MM-DD"
  674. class="w-100"
  675. style="width:100%"
  676. /></el-form-item>
  677. <el-form-item label="事由" prop="electricityList.reason" class="span-full"
  678. ><el-input size="large" placeholder="输入事由" v-model="formValue.electricityList.reason" type="textarea" rows="3" show-word-limit maxlength="300"
  679. /></el-form-item>
  680. <el-form-item label="责任人及联系方式" prop="electricityList.contactPerson"
  681. ><el-input size="large" placeholder="输入责任人及联系方式" v-model="formValue.electricityList.contactPerson" type="textarea" rows="3" show-word-limit maxlength="300"
  682. /></el-form-item>
  683. <el-form-item label="设备及功率" prop="electricityList.equipmentPower"
  684. ><el-input size="large" placeholder="输入设备及功率" v-model="formValue.electricityList.equipmentPower" type="textarea" rows="3" show-word-limit maxlength="300"
  685. /></el-form-item>
  686. <el-form-item label="保护措施" prop="electricityList.safety" class="span-full"
  687. ><el-input size="large" placeholder="输入保护措施" v-model="formValue.electricityList.safety" type="textarea" rows="3" show-word-limit maxlength="300"
  688. /></el-form-item>
  689. <el-form-item label="需求部门负责人" prop="electricityList.deptManager" class="span-full"
  690. ><el-input size="large" placeholder="输入需求部门负责人" v-model="formValue.electricityList.deptManager"
  691. /></el-form-item>
  692. <el-form-item label="建设管理部负责人" prop="electricityList.constructionManager" class="span-full"
  693. ><el-input size="large" placeholder="输入建设管理部负责人" v-model="formValue.electricityList.constructionManager"
  694. /></el-form-item>
  695. <el-form-item label="申请附件" class="span-full" prop="electricityList.attachment">
  696. <!-- <UploadFiles
  697. label="上传附件"
  698. @upload-success="(l) => handleUpload('electricityList', 'attachment', l)"
  699. :fileList="listMap['electricityList.attachment']"
  700. /> -->
  701. <div class="file-list" v-if="listMap['electricityList.attachment'].length > 0">
  702. <div v-for="file in listMap['electricityList.attachment']" :key="file.fileId" class="file-item">
  703. <div class="file-info">
  704. <img :src="FILE_TYPE_ICON[file.fileType as keyof typeof FILE_TYPE_ICON]" />
  705. <span class="file-name">{{ file.fileName }}</span>
  706. </div>
  707. <div link class="fileAction" @click="previewOnline(file.fileUrl, file.fileType as keyof typeof FILE_TYPE_ICON)">预览</div>
  708. <div link class="fileAction" @click.stop="downloadFile(file.fileUrl, file.fileName)">下载</div>
  709. </div>
  710. </div>
  711. </el-form-item>
  712. </div>
  713. </template>
  714. <template v-else-if="formValue.hazardOperationType === 4">
  715. <div class="section-title">动火作业详情</div>
  716. <div class="form-grid" style="width:50%">
  717. <el-form-item label="动火作业地点" prop="hot.hotWorkLocation"
  718. ><el-input size="large" placeholder="输入动火作业地点" v-model="formValue.hot.hotWorkLocation"
  719. /></el-form-item>
  720. <el-form-item label="动火级别" prop="hot.hotWorkLevel">
  721. <el-select v-model="formValue.hot.hotWorkLevel" class="w-100" >
  722. <el-option :value="1" label="一级" />
  723. <el-option :value="2" label="二级" />
  724. <el-option :value="3" label="三级" />
  725. </el-select>
  726. </el-form-item>
  727. <el-form-item label="是否节假日、重大活动及公司启动一级响应期间" prop="hot.isSpecialPeriod">
  728. <el-radio-group v-model="formValue.hot.isSpecialPeriod">
  729. <el-radio :value="1">是</el-radio>
  730. <el-radio :value="0">否</el-radio>
  731. </el-radio-group>
  732. </el-form-item>
  733. <el-form-item label="动火时间起" prop="hot.hotWorkStart"
  734. ><el-date-picker
  735. size="large"
  736. placeholder="输入动火时间起"
  737. v-model="formValue.hot.hotWorkStart"
  738. value-format="YYYY-MM-DD"
  739. style="width:100%"
  740. /></el-form-item>
  741. <el-form-item label="动火时间止" prop="hot.hotWorkEnd"
  742. ><el-date-picker size="large" placeholder="动火时间止" v-model="formValue.hot.hotWorkEnd" value-format="YYYY-MM-DD" style="width:100%"
  743. /></el-form-item>
  744. <el-form-item label="动火任务" prop="hot.hotWorkTask" class="span-full"
  745. ><el-input size="large" placeholder="输入动火任务" v-model="formValue.hot.hotWorkTask"
  746. /></el-form-item>
  747. <el-form-item label="动火类型" prop="hot.hotWorkType"
  748. ><el-input size="large" v-model="formValue.hot.hotWorkType" placeholder="输入动火类型"
  749. /></el-form-item>
  750. <el-form-item label="动火作业人员" prop="hot.hotWorkman"
  751. ><el-input size="large" placeholder="输入动火作业人员" v-model="formValue.hot.hotWorkman"
  752. /></el-form-item>
  753. <el-form-item label="动火人联系电话" prop="hot.hotWorkContact"
  754. ><el-input size="large" placeholder="输入动火人联系电话" v-model="formValue.hot.hotWorkContact"
  755. /></el-form-item>
  756. <el-form-item label="动火危险性分析" prop="hot.hazardAnalysis" class="span-full"
  757. ><el-input size="large" placeholder="输入动火危险性分析" v-model="formValue.hot.hazardAnalysis"
  758. /></el-form-item>
  759. <el-form-item label="消防安全防护措施" prop="hot.fireSafetyMeasures" class="span-full"
  760. ><el-input size="large" placeholder="输入消防安全防护措施" v-model="formValue.hot.fireSafetyMeasures"
  761. /></el-form-item>
  762. </div>
  763. <div class="form-grid" style="width:50%">
  764. <el-form-item label="施工单位指定动火监护人" prop="hot.constructionSupervisor"
  765. ><el-input size="large" placeholder="输入施工单位指定动火监护人" v-model="formValue.hot.constructionSupervisor"
  766. /></el-form-item>
  767. <el-form-item label="施工单位指定动火监护人联系电话" prop="hot.supervisorContact"
  768. ><el-input size="large" placeholder="输入施工单位指定动火监护人联系电话" v-model="formValue.hot.supervisorContact"
  769. /></el-form-item>
  770. <el-form-item label="施工单位现场负责人" prop="hot.constructionSiteLeader"
  771. ><el-input size="large" placeholder="输入施工单位现场负责人" v-model="formValue.hot.constructionSiteLeader"
  772. /></el-form-item>
  773. <el-form-item label="施工单位教育人" prop="hot.constructionEducator"
  774. ><el-input size="large" placeholder="输入施工单位教育人" v-model="formValue.hot.constructionEducator"
  775. /></el-form-item>
  776. <el-form-item label="申请部门指定动火监护人" prop="hot.hotWorkSupervisor"
  777. ><el-input size="large" placeholder="输入申请部门指定动火监护人" v-model="formValue.hot.hotWorkSupervisor"
  778. /></el-form-item>
  779. <el-form-item label="申请部门指定动火监护人联系电话" prop="hot.supervisorNumber"
  780. ><el-input size="large" placeholder="输入申请部门指定动火监护人联系电话" v-model="formValue.hot.supervisorNumber"
  781. /></el-form-item>
  782. </div>
  783. <div class="form-grid" style="width:50%">
  784. <el-form-item label="动火操作现场防护措施及检查情况" prop="hot.supervisorMeasures" class="span-full"
  785. ><el-input size="large" placeholder="输入动火操作现场防护措施及检查情况" v-model="formValue.hot.supervisorMeasures" type="textarea"
  786. /></el-form-item>
  787. <el-form-item label="动火现场检查照片" prop="hot.photos">
  788. <!-- <UploadFiles
  789. label="上传附件"
  790. @upload-success="(l) => handleUpload('hot', 'photos', l)"
  791. :fileList="listMap['hot.photos']"
  792. /> -->
  793. <div class="file-list" v-if="listMap['hot.photos'].length > 0">
  794. <div v-for="file in listMap['hot.photos']" :key="file.fileId" class="file-item">
  795. <div class="file-info">
  796. <img :src="FILE_TYPE_ICON[file.fileType as keyof typeof FILE_TYPE_ICON]" />
  797. <span class="file-name">{{ file.fileName }}</span>
  798. </div>
  799. <div link class="fileAction" @click="previewOnline(file.fileUrl, file.fileType as keyof typeof FILE_TYPE_ICON)">预览</div>
  800. <div link class="fileAction" @click.stop="downloadFile(file.fileUrl, file.fileName)">下载</div>
  801. </div>
  802. </div>
  803. </el-form-item>
  804. <el-form-item label="身份证复印件" prop="hot.idCard">
  805. <!-- <UploadFiles
  806. label="上传附件"
  807. @upload-success="(l) => handleUpload('hot', 'idCard', l)"
  808. :fileList="listMap['hot.idCard']"
  809. /> -->
  810. <div class="file-list" v-if="listMap['hot.idCard'].length > 0">
  811. <div v-for="file in listMap['hot.idCard']" :key="file.fileId" class="file-item">
  812. <div class="file-info">
  813. <img :src="FILE_TYPE_ICON[file.fileType as keyof typeof FILE_TYPE_ICON]" />
  814. <span class="file-name">{{ file.fileName }}</span>
  815. </div>
  816. <div link class="fileAction" @click="previewOnline(file.fileUrl, file.fileType as keyof typeof FILE_TYPE_ICON)">预览</div>
  817. <div link class="fileAction" @click.stop="downloadFile(file.fileUrl, file.fileName)">下载</div>
  818. </div>
  819. </div>
  820. </el-form-item>
  821. <el-form-item label="动火人特种作业操作证复印件" prop="hot.optionCard">
  822. <!-- <UploadFiles
  823. label="上传附件"
  824. @upload-success="(l) => handleUpload('hot', 'optionCard', l)"
  825. :fileList="listMap['hot.optionCard']"
  826. /> -->
  827. <div class="file-list" v-if="listMap['hot.optionCard'].length > 0">
  828. <div v-for="file in listMap['hot.optionCard']" :key="file.fileId" class="file-item">
  829. <div class="file-info">
  830. <img :src="FILE_TYPE_ICON[file.fileType as keyof typeof FILE_TYPE_ICON]" />
  831. <span class="file-name">{{ file.fileName }}</span>
  832. </div>
  833. <div link class="fileAction" @click="previewOnline(file.fileUrl, file.fileType as keyof typeof FILE_TYPE_ICON)">预览</div>
  834. <div link class="fileAction" @click.stop="downloadFile(file.fileUrl, file.fileName)">下载</div>
  835. </div>
  836. </div>
  837. </el-form-item>
  838. <el-form-item label="动火安全教育记录" prop="hot.safetyEducationPlan">
  839. <!-- <UploadFiles
  840. label="上传附件"
  841. @upload-success="(l) => handleUpload('hot', 'safetyEducationPlan', l)"
  842. :fileList="listMap['hot.safetyEducationPlan']"
  843. /> -->
  844. <div class="file-list" v-if="listMap['hot.safetyEducationPlan'].length > 0">
  845. <div v-for="file in listMap['hot.safetyEducationPlan']" :key="file.fileId" class="file-item">
  846. <div class="file-info">
  847. <img :src="FILE_TYPE_ICON[file.fileType as keyof typeof FILE_TYPE_ICON]" />
  848. <span class="file-name">{{ file.fileName }}</span>
  849. </div>
  850. <div link class="fileAction" @click="previewOnline(file.fileUrl, file.fileType as keyof typeof FILE_TYPE_ICON)">预览</div>
  851. <div link class="fileAction" @click.stop="downloadFile(file.fileUrl, file.fileName)">下载</div>
  852. </div>
  853. </div>
  854. </el-form-item>
  855. <el-form-item label="动火作业施工方案" prop="hot.constructionPlan">
  856. <!-- <UploadFiles
  857. label="上传附件"
  858. @upload-success="(l) => handleUpload('hot', 'constructionPlan', l)"
  859. :fileList="listMap['hot.constructionPlan']"
  860. /> -->
  861. <div class="file-list" v-if="listMap['hot.constructionPlan'].length > 0">
  862. <div v-for="file in listMap['hot.constructionPlan']" :key="file.fileId" class="file-item">
  863. <div class="file-info">
  864. <img :src="FILE_TYPE_ICON[file.fileType as keyof typeof FILE_TYPE_ICON]" />
  865. <span class="file-name">{{ file.fileName }}</span>
  866. </div>
  867. <div link class="fileAction" @click="previewOnline(file.fileUrl, file.fileType as keyof typeof FILE_TYPE_ICON)">预览</div>
  868. <div link class="fileAction" @click.stop="downloadFile(file.fileUrl, file.fileName)">下载</div>
  869. </div>
  870. </div>
  871. </el-form-item>
  872. <el-form-item label="动火作业场所准备照片" prop="hot.preparationPhotos">
  873. <!-- <UploadFiles
  874. label="上传附件"
  875. @upload-success="(l) => handleUpload('hot', 'preparationPhotos', l)"
  876. :fileList="listMap['hot.preparationPhotos']"
  877. /> -->
  878. <div class="file-list" v-if="listMap['hot.preparationPhotos'].length > 0">
  879. <div v-for="file in listMap['hot.preparationPhotos']" :key="file.fileId" class="file-item">
  880. <div class="file-info">
  881. <img :src="FILE_TYPE_ICON[file.fileType as keyof typeof FILE_TYPE_ICON]" />
  882. <span class="file-name">{{ file.fileName }}</span>
  883. </div>
  884. <div link class="fileAction" @click="previewOnline(file.fileUrl, file.fileType as keyof typeof FILE_TYPE_ICON)">预览</div>
  885. <div link class="fileAction" @click.stop="downloadFile(file.fileUrl, file.fileName)">下载</div>
  886. </div>
  887. </div>
  888. </el-form-item>
  889. <el-form-item label="特种行业操作证网上查询情况照片" prop="hot.operationCertificates">
  890. <!-- <UploadFiles
  891. label="上传附件"
  892. @upload-success="(l) => handleUpload('hot', 'operationCertificates', l)"
  893. :fileList="listMap['hot.operationCertificates']"
  894. /> -->
  895. <div class="file-list" v-if="listMap['hot.operationCertificates'].length > 0">
  896. <div v-for="file in listMap['hot.operationCertificates']" :key="file.fileId" class="file-item">
  897. <div class="file-info">
  898. <img :src="FILE_TYPE_ICON[file.fileType as keyof typeof FILE_TYPE_ICON]" />
  899. <span class="file-name">{{ file.fileName }}</span>
  900. </div>
  901. <div link class="fileAction" @click="previewOnline(file.fileUrl, file.fileType as keyof typeof FILE_TYPE_ICON)">预览</div>
  902. <div link class="fileAction" @click.stop="downloadFile(file.fileUrl, file.fileName)">下载</div>
  903. </div>
  904. </div>
  905. </el-form-item>
  906. <el-form-item label="动火作业安全管理协议" prop="hot.safetyManagementAgreement">
  907. <!-- <UploadFiles
  908. label="上传附件"
  909. @upload-success="(l) => handleUpload('hot', 'safetyManagementAgreement', l)"
  910. :fileList="listMap['hot.safetyManagementAgreement']"
  911. /> -->
  912. <div class="file-list" v-if="listMap['hot.safetyManagementAgreement'].length > 0">
  913. <div v-for="file in listMap['hot.safetyManagementAgreement']" :key="file.fileId" class="file-item">
  914. <div class="file-info">
  915. <img :src="FILE_TYPE_ICON[file.fileType as keyof typeof FILE_TYPE_ICON]" />
  916. <span class="file-name">{{ file.fileName }}</span>
  917. </div>
  918. <div link class="fileAction" @click="previewOnline(file.fileUrl, file.fileType as keyof typeof FILE_TYPE_ICON)">预览</div>
  919. <div link class="fileAction" @click.stop="downloadFile(file.fileUrl, file.fileName)">下载</div>
  920. </div>
  921. </div>
  922. </el-form-item>
  923. </div>
  924. </template>
  925. <div class="form-line-divider"></div>
  926. <div v-if="formValue.hazardOperationType < 3">
  927. <div class="section-title-flex">
  928. <span class="is-required-manual">安全措施</span>
  929. <el-button type="primary" @click="addRow('measure')">+ 新增措施</el-button>
  930. </div>
  931. <el-table :data="formValue.measure" border class="mb-20">
  932. <el-table-column label="序号" prop="serialNumber" width="100" align="center" />
  933. <el-table-column label="安全措施"
  934. ><template #default="scope"><el-input placeholder="输入安全措施" v-model="scope.row.safetyMeasure" /></template
  935. ></el-table-column>
  936. <el-table-column label="确认人" width="200"
  937. ><template #default="scope"><el-input placeholder="输入确认人" v-model="scope.row.confirmer" /></template
  938. ></el-table-column>
  939. <el-table-column label="操作" width="100" align="center">
  940. <template #default="scope"
  941. ><el-button type="primary" link @click="removeRow('measure', scope.$index)">删除</el-button></template
  942. >
  943. </el-table-column>
  944. </el-table>
  945. </div>
  946. </el-form>
  947. </main>
  948. <footer class="safety-platform-container__footer">
  949. <el-button size="large" @click="router.back()">返回</el-button>
  950. </footer>
  951. <PreviewOnline ref="previewOnlineRef" />
  952. </div>
  953. </template>
  954. <script lang="ts" setup>
  955. import { ref, reactive, onMounted, nextTick } from 'vue';
  956. import { useRouter, useRoute } from 'vue-router';
  957. import { ElMessage } from 'element-plus';
  958. import UploadFiles from '@/components/UploadFiles/UploadFiles.vue';
  959. import { getAllApproval } from '@/api/approval/approval';
  960. import { dangerWorkQueryDetail } from '@/api/production-safety/responsibility-implementation';
  961. import { formatDeptTree } from '@/views/disaster/utils/formatDeptTree';
  962. import { getAllDepartments } from '@/api/auth/dept';
  963. import { unformatAttachment, formatAttachmentList } from '@/components/UploadFiles/utils';
  964. import PreviewOnline from '@/views/disaster/components/PreviewOnline.vue';
  965. import { FILE_TYPE_ICON } from '@/components/UploadFiles/constants';
  966. import type { FileItem } from '@/components/UploadFiles/types';
  967. import { downloadFile } from '@/views/disaster/utils';
  968. const router = useRouter();
  969. const route = useRoute();
  970. const formRef = ref<any>(null);
  971. const detailId = route.query.id as string;
  972. const approvalOptions = ref<any[]>([]);
  973. const firstLevelDepts = ref<any[]>([]);
  974. const cascaderRef = ref<any>(null);
  975. const cascaderProp = { expandTrigger: 'click', checkStrictly: true, value: 'id', label: 'deptName' };
  976. /**
  977. * 1. 附件显示映射 (仅用于组件内部回显显示)
  978. */
  979. const listMap = reactive<any>({
  980. 'space.attachment': [],
  981. 'highAltitude.attachment': [],
  982. 'electricityList.attachment': [],
  983. 'hot.photos': [],
  984. 'hot.idCard': [],
  985. 'hot.optionCard': [],
  986. 'hot.safetyEducationPlan': [],
  987. 'hot.constructionPlan': [],
  988. 'hot.preparationPhotos': [],
  989. 'hot.operationCertificates': [],
  990. 'hot.safetyManagementAgreement': [],
  991. });
  992. /**
  993. * 2. 初始化表单数据结构 (保持深度对象存在)
  994. */
  995. const formValue = reactive<any>({
  996. id: detailId,
  997. templateId: '',
  998. applicationDepartment: '',
  999. applicationDepartmentId: [],
  1000. applicationUnitName: '',
  1001. applicantName: '',
  1002. applicantPhone: '',
  1003. hazardOperationType: '',
  1004. remark: '',
  1005. // 必须预设这些对象,防止赋值时路径不存在
  1006. space: { attachment: '' },
  1007. highAltitude: { attachment: '' },
  1008. electricityList: { attachment: '' },
  1009. hot: {
  1010. photos: '',
  1011. idCard: '',
  1012. optionCard: '',
  1013. safetyEducationPlan: '',
  1014. constructionPlan: '',
  1015. preparationPhotos: '',
  1016. operationCertificates: '',
  1017. safetyManagementAgreement: '',
  1018. },
  1019. measure: [],
  1020. analysis: [],
  1021. });
  1022. const r = { required: true, message: '此项必填', trigger: ['blur', 'change'] };
  1023. const rules = reactive({
  1024. templateId: [r],
  1025. applicationUnitName: [r],
  1026. applicantName: [r],
  1027. applicationDepartment: [r],
  1028. applicantPhone: [r],
  1029. hazardOperationType:[r],
  1030. remark: [r],
  1031. // 有限空间
  1032. 'space.confinedSpaceUnit': [r],
  1033. 'space.confinedSpaceName': [r],
  1034. 'space.unitResponsible': [r],
  1035. 'space.supervisor': [r],
  1036. 'space.operator': [r],
  1037. 'space.otherSpecialOps': [r],
  1038. 'space.operationStartTime': [r],
  1039. 'space.operationEndTime': [r],
  1040. 'space.operationContent': [r],
  1041. 'space.hazardIdentification': [r],
  1042. 'space.attachment':[r],
  1043. // 高处作业
  1044. 'highAltitude.operationLocation': [r],
  1045. 'highAltitude.operationUnit': [r],
  1046. 'highAltitude.operationHeight': [r],
  1047. 'highAltitude.operationType': [r],
  1048. 'highAltitude.operatorName': [r],
  1049. 'highAltitude.supervisor': [r],
  1050. 'highAltitude.operationStartTime': [r],
  1051. 'highAltitude.operationEndTime': [r],
  1052. 'highAltitude.operationContent': [r],
  1053. 'highAltitude.hazardIdentification': [r],
  1054. 'highAltitude.operatorJob':[r],
  1055. 'highAltitude.attachment':[r],
  1056. // 临时用电
  1057. 'electricityList.requestDepartment': [r],
  1058. 'electricityList.electricityType': [r],
  1059. 'electricityList.contactPerson': [r],
  1060. 'electricityList.equipmentPower': [r],
  1061. 'electricityList.operationStartTime': [r],
  1062. 'electricityList.operationEndTime': [r],
  1063. 'electricityList.safety': [r],
  1064. 'electricityList.deptManager': [r],
  1065. 'electricityList.constructionManager':[r],
  1066. 'electricityList.reason': [r],
  1067. 'electricityList.attachment': [r],
  1068. // 动火作业
  1069. 'hot.hotWorkLocation': [r],
  1070. 'hot.hotWorkLevel': [r],
  1071. 'hot.isSpecialPeriod':[r],
  1072. 'hot.hotWorkType': [r],
  1073. 'hot.hotWorkStart': [r],
  1074. 'hot.hotWorkEnd': [r],
  1075. 'hot.hotWorkman': [r],
  1076. 'hot.hotWorkContact': [r],
  1077. 'hot.constructionSupervisor': [r],
  1078. 'hot.supervisorContact': [r],
  1079. 'hot.constructionSiteLeader': [r],
  1080. 'hot.constructionEducator': [r],
  1081. 'hot.hotWorkSupervisor': [r],
  1082. 'hot.supervisorNumber': [r],
  1083. 'hot.hotWorkTask': [r],
  1084. 'hot.hazardAnalysis': [r],
  1085. 'hot.fireSafetyMeasures': [r],
  1086. 'hot.supervisorMeasures': [r],
  1087. // 动火附件
  1088. 'hot.photos': [r],
  1089. 'hot.idCard': [r],
  1090. 'hot.optionCard': [r],
  1091. 'hot.safetyEducationPlan': [r],
  1092. 'hot.constructionPlan': [r],
  1093. 'hot.preparationPhotos': [r],
  1094. 'hot.operationCertificates': [r],
  1095. 'hot.safetyManagementAgreement': [r],
  1096. });
  1097. /**
  1098. * 3. 关键:上传成功回调
  1099. * @param obj 对应的对象名 (如 'space')
  1100. * @param key 对应的字段名 (如 'attachment')
  1101. * @param list 组件返回的最新的 fileList 数组
  1102. */
  1103. const handleUpload = async (obj: string, key: string, list: any[]) => {
  1104. listMap[`${obj}.${key}`] = list;
  1105. if (formValue[obj]) {
  1106. const formatted = await formatAttachmentList(list);
  1107. formValue[obj][key] = formatted.length > 0 ? JSON.stringify(formatted) : '';
  1108. }
  1109. };
  1110. /**
  1111. * 4. 详情回显
  1112. */
  1113. const getDetail = async () => {
  1114. if (!detailId) return;
  1115. try {
  1116. const res = await dangerWorkQueryDetail(detailId);
  1117. res.applicationDepartmentId = JSON.parse(res.applicationDepartmentId)
  1118. // 1. 基础属性拷贝
  1119. Object.assign(formValue, res);
  1120. // 2. 等待 DOM 和 v-if 完成渲染 (确保 Upload 控件已经挂载)
  1121. await nextTick();
  1122. const typeKeyMap: any = { 1: 'space', 2: 'highAltitude', 3: 'electricityList', 4: 'hot' };
  1123. const activeObjName = typeKeyMap[formValue.hazardOperationType];
  1124. if (!activeObjName) return;
  1125. // 3. 附件处理逻辑
  1126. Object.keys(listMap).forEach((path) => {
  1127. // 检查当前路径是否属于选中的作业类型 (例如 "space.attachment")
  1128. if (path.startsWith(activeObjName)) {
  1129. const [objName, fieldName] = path.split('.');
  1130. // 拿到后端返回的原始字段值 (通常是字符串)
  1131. const rawValue = formValue[objName]?.[fieldName];
  1132. if (rawValue) {
  1133. // 【核心修改】:调用你的解析函数,将字符串转为数组
  1134. // 确保 unformatAttachment 函数已在当前作用域可用
  1135. listMap[path] = unformatAttachment(rawValue);
  1136. console.log(`附件解析成功 [${path}]:`, listMap[path]);
  1137. }
  1138. }
  1139. });
  1140. } catch (err) {
  1141. console.error('详情加载失败:', err);
  1142. // ElMessage.error('详情回显失败');
  1143. }
  1144. };
  1145. // 预览
  1146. const previewOnlineRef = ref<InstanceType<typeof PreviewOnline>>();
  1147. const previewOnline = (url: string | undefined, type: keyof typeof FILE_TYPE_ICON) => {
  1148. if (url) {
  1149. previewOnlineRef.value?.open(url, type);
  1150. }
  1151. };
  1152. /**
  1153. * 辅助:表格行操作
  1154. */
  1155. const addRow = (type: 'measure' | 'analysis') => {
  1156. if (type === 'measure') {
  1157. formValue.measure.push({ serialNumber: formValue.measure.length + 1, safetyMeasure: '', confirmer: '' });
  1158. } else {
  1159. formValue.analysis.push({
  1160. toxicSubstance: '',
  1161. flammableGas: '',
  1162. oxygenContent: '',
  1163. analysisTime: '',
  1164. analysisPosition: '',
  1165. analyst: '',
  1166. });
  1167. }
  1168. };
  1169. const removeRow = (type: 'measure' | 'analysis', index: number) => {
  1170. formValue[type].splice(index, 1);
  1171. if (type === 'measure') {
  1172. formValue.measure.forEach((item: any, i: number) => (item.serialNumber = i + 1));
  1173. }
  1174. };
  1175. const handleChangeDept = () => {
  1176. const node = cascaderRef.value?.getCheckedNodes()?.[0];
  1177. if (node) {
  1178. formValue.applicationDepartment = node.label;
  1179. formValue.applicationDepartmentId = node.pathValues;
  1180. }
  1181. };
  1182. onMounted(async () => {
  1183. const [depts, approvals] = await Promise.all([getAllDepartments(), getAllApproval()]);
  1184. firstLevelDepts.value = formatDeptTree(depts);
  1185. approvalOptions.value = approvals || [];
  1186. getDetail();
  1187. });
  1188. </script>
  1189. <style lang="scss" scoped>
  1190. @use '@/styles/page-main-layout.scss' as *;
  1191. @use '@/styles/page-details-layout.scss' as *;
  1192. .safety-platform-container {
  1193. .section-title-flex {
  1194. display: flex;
  1195. justify-content: space-between;
  1196. margin: 15px 0;
  1197. }
  1198. &__main {
  1199. padding: 24px;
  1200. background-color: #fff;
  1201. }
  1202. :deep(.el-form-item) {
  1203. margin-right: 20px;
  1204. margin-bottom: 24px;
  1205. vertical-align: top;
  1206. .el-form-item__label {
  1207. font-weight: bold;
  1208. }
  1209. }
  1210. }
  1211. .file-list {
  1212. margin-top: 16px;
  1213. display: flex;
  1214. flex-wrap: wrap;
  1215. gap: 8px;
  1216. &:first-child {
  1217. margin-top: 0;
  1218. }
  1219. }
  1220. .file-item {
  1221. @include flex-center;
  1222. justify-content: space-between;
  1223. gap: 10px;
  1224. height: 32px;
  1225. border: 1px solid #e5e7eb;
  1226. border-radius: 6px;
  1227. padding: 12px;
  1228. transition: all 0.2s ease;
  1229. &:hover {
  1230. background-color: #f8fafc;
  1231. }
  1232. }
  1233. .file-info {
  1234. display: flex;
  1235. align-items: center;
  1236. gap: 8px;
  1237. img {
  1238. width: 10px;
  1239. }
  1240. }
  1241. .file-name {
  1242. flex: 1;
  1243. overflow: hidden;
  1244. text-overflow: ellipsis;
  1245. white-space: nowrap;
  1246. font-size: 14px;
  1247. color: rgba($text-color, 0.65);
  1248. }
  1249. .fileAction {
  1250. width: 60px;
  1251. text-align: center;
  1252. cursor: pointer;
  1253. color: #1777ff;
  1254. }
  1255. .delete-button {
  1256. color: #ef4444;
  1257. background: none;
  1258. border: none;
  1259. cursor: pointer;
  1260. font-size: 12px;
  1261. }
  1262. :deep(.preview-img){
  1263. overflow: auto;
  1264. img {
  1265. max-height: 90vh;
  1266. }
  1267. }
  1268. </style>