areaCheckPlanManagementDeptDetail.vue 44 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217
  1. <template>
  2. <!-- 区域检查计划管理(部门)查看:与管理员查看样式一致 -->
  3. <main class="safety-platform-container__main area-check-plan-view">
  4. <section class="view-section view-summary">
  5. <div class="view-summary__title">一级危险点:{{ viewDetail.checkVenue || '-' }}</div>
  6. <div class="view-summary__meta">
  7. <span>检查类别:{{ viewDetail.venueCategoryName || '-' }}</span>
  8. <span>创建人:{{ viewDetail.createdPersonName || '-' }}</span>
  9. <span>创建时间:{{ viewDetail.createdAt || '-' }}</span>
  10. </div>
  11. </section>
  12. <section class="view-section audit-content">
  13. <h4 class="section-title">
  14. <el-icon class="section-title__icon"><Document /></el-icon>
  15. <span>基本信息</span>
  16. </h4>
  17. <div class="detail-ct detail-ct--table">
  18. <div class="row">
  19. <div class="col">
  20. <div class="label">区域计划名称:</div>
  21. <div class="value">{{ viewDetail.planName || '-' }}</div>
  22. </div>
  23. <div class="col">
  24. <div class="label">状态:</div>
  25. <div class="value">{{ viewDetail.statusName || '进行中' }}</div>
  26. </div>
  27. </div>
  28. <div class="row">
  29. <div class="col">
  30. <div class="label">主责部门:</div>
  31. <div class="value">{{ viewDetail.primaryResponsibleDeptName || '-' }}</div>
  32. </div>
  33. <div class="col">
  34. <div class="label">自查频率:</div>
  35. <div class="value">{{ viewDetail.selfCheckFrequency || '-' }}</div>
  36. </div>
  37. </div>
  38. <div class="row">
  39. <div class="col">
  40. <div class="label">主责部门执行人所属分组名称:</div>
  41. <div class="value">{{ viewDetail.primaryResponsibleDeptExecGroupName || '-' }}</div>
  42. </div>
  43. <div class="col">
  44. <div class="label">主责部门责任人:</div>
  45. <div class="value">{{ viewDetail.primaryResponsibleDeptPersonName || '-' }}</div>
  46. </div>
  47. </div>
  48. <div class="row">
  49. <div class="col">
  50. <div class="label">安全应急部部门名称:</div>
  51. <div class="value">{{ viewDetail.safetyEmergencyDeptName || '-' }}</div>
  52. </div>
  53. <div class="col">
  54. <div class="label">安全应急部检查频次:</div>
  55. <div class="value">{{ viewDetail.safetyEmergencyCheckFrequency || '-' }}</div>
  56. </div>
  57. </div>
  58. <div class="row">
  59. <div class="col">
  60. <div class="label">安全应急部执行人所属分组名称:</div>
  61. <div class="value">{{ viewDetail.safetyEmergencyExecutorGroupName || '-' }}</div>
  62. </div>
  63. <div class="col">
  64. <div class="label">安全应急部责任人:</div>
  65. <div class="value">{{ viewDetail.safetyEmergencyResponsiblePerson || '-' }}</div>
  66. </div>
  67. </div>
  68. <div class="row">
  69. <div class="col">
  70. <div class="label">院领导部门名称:</div>
  71. <div class="value">{{ viewDetail.hospitalLeaderDeptName || '-' }}</div>
  72. </div>
  73. <div class="col">
  74. <div class="label">院领导检查频次:</div>
  75. <div class="value">{{ viewDetail.hospitalLeaderCheckFrequency || '-' }}</div>
  76. </div>
  77. </div>
  78. <div class="row">
  79. <div class="col">
  80. <div class="label">院领导执行人所属分组名称:</div>
  81. <div class="value">{{ viewDetail.hospitalLeaderExecutorGroupName || '-' }}</div>
  82. </div>
  83. <div class="col">
  84. <div class="label">院领导责任人:</div>
  85. <div class="value">{{ viewDetail.hospitalLeaderResponsiblePerson || '-' }}</div>
  86. </div>
  87. </div>
  88. <div class="row">
  89. <div class="col">
  90. <div class="label">检查单所属类别名称:</div>
  91. <div class="value">{{ viewDetail.categoryName || '-' }}</div>
  92. </div>
  93. <div class="col">
  94. <div class="label">检查单模版名称:</div>
  95. <div class="value">{{ viewDetail.checklistTemplateName || '-' }}</div>
  96. </div>
  97. </div>
  98. <div class="row">
  99. <div class="col">
  100. <div class="label">是否需要整体检查情况描述:</div>
  101. <div class="value">{{ viewDetail.needOverallDesc === true ? '是' : viewDetail.needOverallDesc === false ? '否' : '-' }}</div>
  102. </div>
  103. <div class="col">
  104. <div class="label">是否需要被检查人签字:</div>
  105. <div class="value">{{ viewDetail.needSigneeSign === true ? '是' : viewDetail.needSigneeSign === false ? '否' : '-' }}</div>
  106. </div>
  107. </div>
  108. <div class="row">
  109. <div class="col">
  110. <div class="label">计划开始日期:</div>
  111. <div class="value">{{ viewDetail.planStartTime || '-' }}</div>
  112. </div>
  113. <div class="col">
  114. <div class="label">计划完成日期:</div>
  115. <div class="value">{{ viewDetail.planEndTime || '-' }}</div>
  116. </div>
  117. </div>
  118. <div class="row">
  119. <div class="col">
  120. <div class="label">检查内容:</div>
  121. <div class="value value--list">
  122. <ol class="inspection-content-list">
  123. <li v-for="(item, i) in inspectionContentList" :key="i">{{ item }}</li>
  124. </ol>
  125. </div>
  126. </div>
  127. <div class="col">
  128. <div class="label">业务工作:</div>
  129. <div class="value">{{ viewDetail.businessWork || '-' }}</div>
  130. </div>
  131. </div>
  132. </div>
  133. </section>
  134. <section class="view-section">
  135. <div class="view-section__title">
  136. <span class="view-section__icon"></span>
  137. 检查记录
  138. </div>
  139. <div style="margin-bottom: 20px;">
  140. <el-button type="primary" @click="onAddRecord">新增检查日志</el-button>
  141. </div>
  142. <div class="view-record-toolbar">
  143. <el-input
  144. v-model="recordSearchKeyword"
  145. placeholder="检查场所类别/检查场所/检查人员"
  146. clearable
  147. style="width: 280px; margin-right: 12px"
  148. />
  149. <el-date-picker
  150. v-model="recordDateRange"
  151. type="daterange"
  152. range-separator="-"
  153. start-placeholder="开始日期"
  154. end-placeholder="结束日期"
  155. value-format="YYYY-MM-DD"
  156. style="margin-right: 12px;max-width: 280px;"
  157. />
  158. <el-button type="primary" class="view-record-toolbar-btn" @click="onRecordSearch">查询</el-button>
  159. <el-button @click="onRecordExport">导出</el-button>
  160. </div>
  161. <BasicTable
  162. :tableData="paginatedRecordList"
  163. :tableConfig="recordTableConfig"
  164. class="view-record-table"
  165. @update:pageSize="handleRecordSizeChange"
  166. @update:pageNumber="handleRecordPageChange"
  167. >
  168. <template #unqualifiedItemNum="scope">
  169. <el-button
  170. type="primary"
  171. link
  172. size="small"
  173. @click="openUnqualifiedDialog(scope.row)"
  174. >
  175. {{ scope.row.unqualifiedItemNum ?? 0 }}
  176. </el-button>
  177. </template>
  178. <template #sign="scope">
  179. <template v-if="JSON.parse(scope.row.checkedPersonSign || '[]').length">
  180. <div
  181. class="file-container--div"
  182. v-for="item in JSON.parse(scope.row.checkedPersonSign || '[]')"
  183. :key="item.fileUrl || item.fileName"
  184. >
  185. <img
  186. class="file-container--div__icon"
  187. :src="FILE_TYPE_ICON[item.fileType as keyof typeof FILE_TYPE_ICON]"
  188. @click="previewOnline(item.fileUrl, item.fileType as keyof typeof FILE_TYPE_ICON)"
  189. />
  190. <span
  191. class="file-container--div__name"
  192. @click="previewOnline(item.fileUrl, item.fileType as keyof typeof FILE_TYPE_ICON)"
  193. >{{ item.fileName }}</span
  194. >
  195. <img
  196. class="file-container--div__download"
  197. :src="DownloadIcon"
  198. @click="downloadFile(item.fileUrl, item.fileName)"
  199. />
  200. </div>
  201. </template>
  202. <span v-else>-</span>
  203. </template>
  204. <template #action="scope">
  205. <el-button type="primary" link size="small" @click="onViewRecord(scope.row)">检查记录查看</el-button>
  206. </template>
  207. </BasicTable>
  208. </section>
  209. </main>
  210. <PreviewOnline ref="previewOnlineRef" />
  211. <!-- 检查不合格数据弹窗(部门) -->
  212. <el-dialog
  213. v-model="showUnqualifiedDialog"
  214. title="检查不合格数据"
  215. width="800px"
  216. destroy-on-close
  217. >
  218. <BasicTable
  219. :tableData="unqualifiedList"
  220. :tableConfig="unqualifiedTableConfig"
  221. @update:pageSize="handleUnqualifiedSizeChange"
  222. @update:pageNumber="handleUnqualifiedPageChange"
  223. >
  224. <template #action="scope">
  225. <el-button
  226. v-if="Number(scope.row.IsSand) == 0"
  227. type="primary"
  228. link
  229. size="small"
  230. @click="handleSandToHiddenDangerDept(scope.row)"
  231. >
  232. 入账
  233. </el-button>
  234. <span v-else-if="Number(scope.row.IsSand) == 1" style="color: #999999">已入账</span>
  235. <span v-else>-</span>
  236. </template>
  237. </BasicTable>
  238. </el-dialog>
  239. <!-- 部门端:检查记录入账隐患台账确认弹窗(仅查看提示,不真正入账) -->
  240. <el-dialog
  241. v-model="showSandConfirmDialogDept"
  242. title="检查记录入账隐患台账"
  243. width="900px"
  244. destroy-on-close
  245. >
  246. <el-form ref="sandHiddenDangerFormRefDept" label-width="150px" :model="sandHiddenDangerFormDataDept" :rules="sandHiddenDangerFormRulesDept">
  247. <el-form-item prop="typeId" label="隐患问题类别:" style="width: 70%;">
  248. <el-select
  249. v-model="sandHiddenDangerFormDataDept.typeId"
  250. placeholder="请选择隐患问题类别"
  251. filterable
  252. clearable
  253. style="width: 100%"
  254. >
  255. <el-option
  256. v-for="item in dangerTypeList"
  257. :key="item.id"
  258. :label="item.categoryName"
  259. :value="item.id"
  260. />
  261. </el-select>
  262. </el-form-item>
  263. <el-form-item label="隐患问题:" prop="dangerProblem">
  264. <el-input
  265. v-model="sandHiddenDangerFormDataDept.dangerProblem"
  266. placeholder="请输入隐患问题描述"
  267. style="width: 450px"
  268. />
  269. </el-form-item>
  270. <el-form-item label="问题主要原因:" prop="reasonId">
  271. <el-select
  272. v-model="sandHiddenDangerFormDataDept.reasonId"
  273. placeholder="请选择问题主要原因"
  274. clearable
  275. filterable
  276. style="width: 450px"
  277. >
  278. <el-option
  279. v-for="option in REASON_OPTIONS"
  280. :key="option.value"
  281. :label="option.label"
  282. :value="option.value"
  283. />
  284. </el-select>
  285. </el-form-item>
  286. <el-form-item label="任务来源:" prop="taskSource">
  287. <el-input
  288. v-model="sandHiddenDangerFormDataDept.taskSource"
  289. placeholder="如:上级检查、院内自查"
  290. style="width: 450px"
  291. />
  292. </el-form-item>
  293. <el-form-item label="整改要求:" prop="rectificationRequirement">
  294. <el-input
  295. v-model="sandHiddenDangerFormDataDept.rectificationRequirement"
  296. placeholder="请输入整改要求"
  297. style="width: 450px"
  298. />
  299. </el-form-item>
  300. <el-form-item prop="rectificationDepartmentIds" label="整改责任部门:">
  301. <el-cascader
  302. ref="cascaderDeptRef"
  303. v-model="sandHiddenDangerFormDataDept.rectificationDepartmentIds"
  304. :options="issueDeptTree"
  305. :props="cascaderDeptProp"
  306. :show-all-levels="false"
  307. placeholder="请选择整改责任部门"
  308. filterable
  309. clearable
  310. style="width: 450px"
  311. @change="onIssueDeptChange"
  312. />
  313. </el-form-item>
  314. <el-form-item prop="rectificationResponsibleIds" label="整改负责人">
  315. <el-select
  316. v-model="sandHiddenDangerFormDataDept.rectificationResponsibleIds"
  317. placeholder="选择整改负责人"
  318. filterable
  319. clearable
  320. style="width: 450px"
  321. >
  322. <el-option
  323. v-for="user in issueUserList"
  324. :key="user.id"
  325. :label="user.realname ?? user.username"
  326. :value="user.id"
  327. />
  328. </el-select>
  329. </el-form-item>
  330. <el-form-item label="整改日期:" prop="rectificationDeadline">
  331. <el-date-picker
  332. v-model="sandHiddenDangerFormDataDept.rectificationDeadline"
  333. type="date"
  334. value-format="YYYY-MM-DD"
  335. placeholder="请选择整改日期"
  336. style="width: 450px"
  337. />
  338. </el-form-item>
  339. <el-form-item prop="reviewDepartmentId" label="复查人员所属部门:">
  340. <el-cascader
  341. v-model="sandHiddenDangerFormDataDept.reviewDepartmentId"
  342. :options="deptTree"
  343. :props="cascaderDeptProp"
  344. :show-all-levels="false"
  345. placeholder="请选择复查人员所属部门"
  346. filterable
  347. clearable
  348. style="width: 450px"
  349. />
  350. </el-form-item>
  351. <el-form-item label="复查人员:" prop="reviewPersonId">
  352. <el-select
  353. v-model="sandHiddenDangerFormDataDept.reviewPersonId"
  354. placeholder="请选择复查人员"
  355. clearable
  356. filterable
  357. style="width: 450px"
  358. >
  359. <el-option
  360. v-for="u in reviewUserListDept"
  361. :key="u.id"
  362. :label="u.realname || u.username"
  363. :value="u.id"
  364. />
  365. </el-select>
  366. </el-form-item>
  367. <el-form-item label="举一反三是否推送:" prop="isDrawLessonsPush">
  368. <el-radio-group v-model="sandHiddenDangerFormDataDept.isDrawLessonsPush" >
  369. <el-radio :value="0">否</el-radio>
  370. <el-radio :value="1">是</el-radio>
  371. </el-radio-group>
  372. </el-form-item>
  373. <el-form-item label-width="150px" v-if="sandHiddenDangerFormDataDept.isDrawLessonsPush === 1">
  374. <el-input placeholder="如:上级检查、院内自查" style="width: 450px" v-model="sandHiddenDangerFormDataDept.drawLessonsContent" />
  375. </el-form-item>
  376. <el-form-item prop="drawLessonsDepartmentIds" v-if="sandHiddenDangerFormDataDept.isDrawLessonsPush === 1" label="举一反三责任部门:">
  377. <el-select
  378. v-model="drawLessonsDeptIdsArrayDept"
  379. placeholder="请选择举一反三责任部门,可多选"
  380. clearable
  381. filterable
  382. multiple
  383. collapse-tags
  384. collapse-tags-tooltip
  385. style="width: 450px"
  386. @change="() => { sandHiddenDangerFormDataDept.drawLessonsDepartmentIds = drawLessonsDeptIdsArrayDept.join(','); }"
  387. >
  388. <el-option
  389. v-for="d in deptOptions"
  390. :key="d.id"
  391. :label="d.deptName"
  392. :value="d.id"
  393. />
  394. </el-select>
  395. </el-form-item>
  396. <el-form-item prop="drawLessonsDeadline" label="举一反三时限:" v-if="sandHiddenDangerFormDataDept.isDrawLessonsPush === 1">
  397. <el-date-picker
  398. v-model="sandHiddenDangerFormDataDept.drawLessonsDeadline"
  399. type="date"
  400. style="width: 450px"
  401. value-format="YYYY-MM-DD"
  402. placeholder="请选择举一反三截止日期(选填)"
  403. />
  404. </el-form-item>
  405. </el-form>
  406. <!-- <BasicForm
  407. ref="sandHiddenDangerFormRefDept"
  408. :formData="sandHiddenDangerFormDataDept"
  409. :formRules="sandHiddenDangerFormRulesDept"
  410. :formConfig="sandHiddenDangerFormConfigDept"
  411. >
  412. <template #typeId>
  413. <el-form-item prop="typeId" style="width: 100%;">
  414. <el-select
  415. v-model="sandHiddenDangerFormDataDept.typeId"
  416. placeholder="请选择隐患问题类别"
  417. filterable
  418. clearable
  419. style="width: 100%"
  420. >
  421. <el-option
  422. v-for="item in dangerTypeList"
  423. :key="item.id"
  424. :label="item.categoryName"
  425. :value="item.id"
  426. />
  427. </el-select>
  428. </el-form-item>
  429. </template>
  430. <template #rectificationDepartmentIds>
  431. <el-form-item prop="rectificationDepartmentIds" style="width: 100%;">
  432. <el-cascader
  433. ref="cascaderDeptRef"
  434. v-model="sandHiddenDangerFormDataDept.rectificationDepartmentIds"
  435. :options="issueDeptTree"
  436. :props="cascaderDeptProp"
  437. :show-all-levels="false"
  438. placeholder="请选择整改责任部门"
  439. filterable
  440. clearable
  441. @change="onIssueDeptChange"
  442. />
  443. </el-form-item>
  444. </template>
  445. <template #rectificationResponsibleIds>
  446. <el-form-item prop="rectificationResponsibleIds" style="width: 100%;">
  447. <el-select
  448. v-model="sandHiddenDangerFormDataDept.rectificationResponsibleIds"
  449. placeholder="选择整改负责人"
  450. filterable
  451. clearable
  452. style="width: 100%"
  453. >
  454. <el-option
  455. v-for="user in issueUserList"
  456. :key="user.id"
  457. :label="user.realname ?? user.username"
  458. :value="user.id"
  459. />
  460. </el-select>
  461. </el-form-item>
  462. </template>
  463. <template #reviewDepartmentId>
  464. <el-cascader
  465. v-model="sandHiddenDangerFormDataDept.reviewDepartmentId"
  466. :options="deptTree"
  467. :props="cascaderDeptProp"
  468. :show-all-levels="false"
  469. placeholder="请选择复查人员所属部门"
  470. filterable
  471. clearable
  472. style="width: 100%"
  473. />
  474. </template>
  475. <template #reviewPerson>
  476. <el-select
  477. v-model="sandHiddenDangerFormDataDept.reviewPersonId"
  478. placeholder="请选择复查人员"
  479. clearable
  480. filterable
  481. style="width: 100%"
  482. >
  483. <el-option
  484. v-for="u in reviewUserListDept"
  485. :key="u.id"
  486. :label="u.realname || u.username"
  487. :value="u.id"
  488. />
  489. </el-select>
  490. </template>
  491. <template #isDrawLessonsPush>
  492. <el-radio-group v-model="sandHiddenDangerFormDataDept.isDrawLessonsPush" @change="isDrawLessonsPushChange">
  493. <el-radio :value="0">否</el-radio>
  494. <el-radio :value="1">是</el-radio>
  495. </el-radio-group>
  496. </template>
  497. <template #drawLessonsContent v-if="sandHiddenDangerFormDataDept.isDrawLessonsPush === 1">
  498. <el-form-item label-width="136.5px" style="width:100%">
  499. <el-input placeholder="如:上级检查、院内自查" v-model="sandHiddenDangerFormDataDept.drawLessonsContent" />
  500. </el-form-item>
  501. </template>
  502. <template #drawLessonsDepartmentId v-if="sandHiddenDangerFormDataDept.isDrawLessonsPush === 1">
  503. <el-form-item prop="drawLessonsDepartmentIds" style="width: 100%" label="举一反三责任部门:">
  504. <el-select
  505. v-model="drawLessonsDeptIdsArrayDept"
  506. placeholder="请选择举一反三责任部门,可多选"
  507. clearable
  508. filterable
  509. multiple
  510. collapse-tags
  511. collapse-tags-tooltip
  512. style="width: 100%"
  513. @change="() => { sandHiddenDangerFormDataDept.drawLessonsDepartmentIds = drawLessonsDeptIdsArrayDept.join(','); }"
  514. >
  515. <el-option
  516. v-for="d in deptOptions"
  517. :key="d.id"
  518. :label="d.deptName"
  519. :value="d.id"
  520. />
  521. </el-select>
  522. </el-form-item>
  523. </template>
  524. <template #drawLessonsDeadline v-if="sandHiddenDangerFormDataDept.isDrawLessonsPush === 1">
  525. <el-form-item prop="drawLessonsDeadline" label="举一反三时限:" style="width: 100%;">
  526. <el-date-picker
  527. v-model="sandHiddenDangerFormDataDept.drawLessonsDeadline"
  528. type="date"
  529. value-format="YYYY-MM-DD"
  530. placeholder="请选择举一反三截止日期(选填)"
  531. />
  532. </el-form-item>
  533. </template>
  534. </BasicForm> -->
  535. <template #footer>
  536. <el-button @click="showSandConfirmDialogDept = false">取消</el-button>
  537. <el-button type="primary" :loading="sandConfirmLoadingDept" @click="confirmSandToHiddenDangerDept">
  538. 提交
  539. </el-button>
  540. </template>
  541. </el-dialog>
  542. </template>
  543. <script setup lang="ts">
  544. import { computed, onMounted, ref } from 'vue';
  545. import { useRoute, useRouter } from 'vue-router';
  546. import { ElMessage } from 'element-plus';
  547. import { Document } from '@element-plus/icons-vue';
  548. import BasicTable from '@/components/BasicTable.vue';
  549. import { FILE_TYPE_ICON } from '@/components/UploadFiles/constants';
  550. import DownloadIcon from '@/views/disaster/disaster-control/src/svg/download.svg';
  551. import PreviewOnline from '@/views/disaster/components/PreviewOnline.vue';
  552. import { downloadFile } from '@/views/disaster/utils';
  553. import useTableConfig from '@/hooks/useTableConfigHook';
  554. import type { TableColumnProps } from '@/types/basic-table';
  555. import { AREA_CHECK_PLAN_STATUS_LABEL} from '../../areaCheckPlanManagement/configs/status';
  556. import {
  557. queryAreaCheckPlanManageDeptDetail,
  558. queryAreaCheckPlanDetailDeptPage,
  559. mapAreaCheckPlanApiRecordToUi,
  560. queryUnqualifiedItemNumDeptPage,
  561. sandAreaCheckRecordToProductionHiddenDanger,
  562. exportAreaCheckInspectionRecord,
  563. type UnqualifiedItemNumRecord,
  564. type SandAreaCheckRecordToHiddenDangerReq,
  565. } from '@/api/production-safety-system';
  566. import { HIDDEN_DANGER_FORM_CONFIG, HIDDEN_DANGER_FORM_RULES, REASON_OPTIONS, HIDDEN_DANGER_FORM_DATA } from "../configs/form"
  567. import BasicForm from '@/components/BasicForm.vue';
  568. import { useFormConfigHook } from '@/hooks/useFormConfigHook';
  569. import { getAllDepartments } from '@/api/auth/dept';
  570. import type { DeptTree } from '@/types/dept/type';
  571. import { queryAvailableUserList } from '@/api/production-safety/responsibility-implementation';
  572. import { downloadByData } from '@/utils/file/download';
  573. import {
  574. queryDangerTypePage,
  575. } from '@/api/production-safety';
  576. import type { CascaderInstance } from 'element-plus'
  577. import { rules } from '../../../../../types/camera/constant';
  578. const router = useRouter();
  579. const route = useRoute();
  580. const currentId = computed(() => Number(route.query.id));
  581. const viewDetailData = ref<Record<string, unknown>>({});
  582. const viewDetail = computed(() => {
  583. const d = viewDetailData.value;
  584. const status = d?.status as number | undefined;
  585. console.log(d,'d')
  586. return {
  587. ...d,
  588. statusName: status != null ? AREA_CHECK_PLAN_STATUS_LABEL[String(status)] ?? '-' : '-',
  589. planName: d?.planName ?? '-',
  590. venueCategoryName: d?.venueCategoryName ?? '-',
  591. checkVenue: d?.checkVenue ?? '-',
  592. mainDeptName: d?.mainDeptName ?? '-',
  593. primaryResponsibleDeptName: (d?.primaryResponsibleDeptName ?? d?.mainDeptName) ?? '-',
  594. selfCheckFrequency: d?.selfCheckFrequency ?? '-',
  595. mainDeptExecutorGroupName: d?.mainDeptExecutorGroupName ?? '-',
  596. mainDeptResponsiblePerson: d?.mainDeptResponsiblePerson ?? '-',
  597. safetyEmergencyDeptName: d?.safetyEmergencyDeptName ?? '-',
  598. safetyEmergencyCheckFrequency: d?.safetyEmergencyCheckFrequency ?? '-',
  599. safetyEmergencyExecutorGroupName: d?.safetyEmergencyExecutorGroupName ?? '-',
  600. safetyEmergencyResponsiblePerson: d?.safetyEmergencyResponsiblePerson ?? '-',
  601. hospitalLeaderDeptName: d?.hospitalLeaderDeptName ?? '-',
  602. hospitalLeaderCheckFrequency: d?.hospitalLeaderCheckFrequency ?? '-',
  603. hospitalLeaderExecutorGroupName: d?.hospitalLeaderExecutorGroupName ?? '-',
  604. hospitalLeaderResponsiblePerson: d?.hospitalLeaderResponsiblePerson ?? '-',
  605. checklistCategoryName: d?.checklistCategoryName ?? '-',
  606. categoryName: (d?.categoryName ?? d?.checklistCategoryName) ?? '-',
  607. checklistTemplateName: d?.checklistTemplateName ?? '-',
  608. needOverallDesc: d?.needOverallDesc,
  609. needSigneeSign: d?.needSigneeSign,
  610. planStartTime: d?.planStartTime ?? '-',
  611. planEndTime: d?.planEndTime ?? '-',
  612. createdPersonName: (d?.createdPersonName ?? '') || '-',
  613. createdAt: (d?.createdAt ?? '') || '-',
  614. businessWork: (d?.businessWork ?? '') || '-',
  615. primaryResponsibleDeptExecGroupName: d?.primaryResponsibleDeptExecGroupName ?? '-',
  616. primaryResponsibleDeptPersonName: d?.primaryResponsibleDeptPersonName ?? '-',
  617. };
  618. });
  619. const issueDeptTree = ref<DeptTree[]>([]);
  620. const issueUserList = ref<Array<{ id: number; realname?: string; username?: string }>>([]);
  621. const onIssueDialogOpen = async () => {
  622. try {
  623. const [deptRes, userRes] = await Promise.all([
  624. getAllDepartments(),
  625. queryAvailableUserList({ pageNumber: 1, pageSize: 9999, queryParam: {} }),
  626. ]);
  627. const fullTree = (deptRes as DeptTree[]) ?? [];
  628. issueDeptTree.value = Array.isArray(fullTree) && fullTree[0]?.children ? fullTree[0].children : [];
  629. issueUserList.value = (userRes as any)?.records ?? [];
  630. } catch (e:any) {
  631. console.error('获取部门/用户列表失败:', e);
  632. ElMessage.error(e?.message || e?.data || '加载部门或负责人列表失败');
  633. issueDeptTree.value = [];
  634. issueUserList.value = [];
  635. }
  636. };
  637. const inspectionContentList = computed(() => {
  638. const content = (viewDetailData.value?.checkKeyContent ?? '') as string;
  639. if (!content || typeof content !== 'string') {
  640. return [
  641. '工作场所布局是否合理,通道是否畅通;',
  642. '各种机械、电力、电气等设备的安装和使用是否符合安全技术要求;',
  643. '安全防护装置是否齐全、灵敏、有效;',
  644. '易燃易爆、有限空间和高处作业等作业场所是否符合安全条件;',
  645. '有较大危险因素和职业危害因素的科研试验场所和有关;',
  646. ];
  647. }
  648. return content.split(/[;;]/).map((s) => s.trim()).filter(Boolean);
  649. });
  650. const RECORD_TABLE_COLUMNS: TableColumnProps[] = [
  651. { label: '编号', type: 'index', align: 'center', width: '80px' },
  652. { label: '检查时间', prop: 'checkTime', minWidth: '160px' },
  653. { label: '检查人员', prop: 'checkPerson', minWidth: '100px' },
  654. { label: '检查场所类别', prop: 'checkPlaceCategory', minWidth: '120px' },
  655. { label: '检查场所', prop: 'checkPlace', minWidth: '120px' },
  656. { label: '检查项总数', prop: 'checkItemTotal', align: 'center', width: '100px' },
  657. { label: '合格项数', prop: 'qualifiedItemNum', align: 'center', width: '90px' },
  658. { label: '不合格项数', prop: 'unqualifiedItemNum', slot: 'unqualifiedItemNum', align: 'center', width: '100px' },
  659. { label: '整体检查情况描述', prop: 'overallCheckDesc', minWidth: '180px', showOverflowTooltip: true },
  660. { label: '被检查人签字', slot: 'sign', align: 'center', width: '140px' },
  661. { label: '操作', slot: 'action', align: 'center', width: '160px', fixed: 'right' },
  662. ];
  663. const RECORD_TABLE_OPTIONS = {
  664. emptyText: '暂无检查记录',
  665. loading: false,
  666. maxHeight: '400px',
  667. stripe: true,
  668. };
  669. const { tableConfig: recordTableConfig, pagination: recordPagination } = useTableConfig(
  670. RECORD_TABLE_COLUMNS,
  671. RECORD_TABLE_OPTIONS,
  672. true,
  673. );
  674. const recordSearchKeyword = ref('');
  675. const recordDateRange = ref<[string, string] | null>(null);
  676. const inspectionRecordList = ref<Array<Record<string, unknown>>>([]);
  677. const paginatedRecordList = computed(() => inspectionRecordList.value);
  678. // 检查不合格数据弹窗
  679. const showUnqualifiedDialog = ref(false);
  680. const currentRecordIdForUnqualified = ref<number | null>(null);
  681. const currentRowForUnqualified = ref<Record<string, unknown> | null>(null);
  682. const unqualifiedList = ref<UnqualifiedItemNumRecord[]>([]);
  683. const UNQUALIFIED_TABLE_COLUMNS: TableColumnProps[] = [
  684. { label: '编号', type: 'index', align: 'center', width: '80px' },
  685. { label: '检查场所', prop: 'checkPlace', minWidth: '200px' },
  686. { label: '发现问题', prop: 'checkProblem', minWidth: '220px' },
  687. { label: '检查时间', prop: 'checkTime', minWidth: '180px' },
  688. { label: '操作', slot: 'action', align: 'center', width: '100px' },
  689. ];
  690. const UNQUALIFIED_TABLE_OPTIONS = {
  691. emptyText: '暂无不合格数据',
  692. loading: false,
  693. maxHeight: '400px',
  694. stripe: true,
  695. };
  696. const { tableConfig: unqualifiedTableConfig, pagination: unqualifiedPagination } = useTableConfig(
  697. UNQUALIFIED_TABLE_COLUMNS,
  698. UNQUALIFIED_TABLE_OPTIONS,
  699. true,
  700. );
  701. // 部门端入账弹窗数据(复用隐患台账新增表单字段与样式)
  702. const showSandConfirmDialogDept = ref(false);
  703. const sandConfirmLoadingDept = ref(false);
  704. const sandHiddenDangerFormRefDept = ref<InstanceType<typeof BasicForm>>();
  705. const {
  706. ruleFormData: sandHiddenDangerFormDataDept,
  707. formRules: sandHiddenDangerFormRulesDept,
  708. ruleFormConfig: sandHiddenDangerFormConfigDept,
  709. } = useFormConfigHook(
  710. HIDDEN_DANGER_FORM_CONFIG,
  711. HIDDEN_DANGER_FORM_DATA as Record<string, unknown>,
  712. HIDDEN_DANGER_FORM_RULES,
  713. );
  714. // 隐患类别数据
  715. const dangerTypeList = ref<any[]>([])
  716. const getTableData = async ()=> {
  717. try {
  718. // 将日期范围同步到查询参数
  719. let params = {
  720. pageNumber: 1,
  721. pageSize: 1000,
  722. queryParam: {
  723. status: 1,
  724. },
  725. }
  726. const res = await queryDangerTypePage(params);
  727. if (res) {
  728. dangerTypeList.value = res.records || [];
  729. }
  730. } catch (e) {
  731. console.error('获取隐患类别列表失败:', e);
  732. dangerTypeList.value = [];
  733. }
  734. }
  735. // 复用部门树与用户下拉,用于复查部门/人员 & 举一反三责任部门
  736. const deptTree = ref<DeptTree[]>([]);
  737. const cascaderDeptProp = {
  738. checkStrictly: true,
  739. expandTrigger: 'hover' as const,
  740. value: 'id',
  741. label: 'deptName',
  742. emitPath: false,
  743. };
  744. function flattenDeptTree(nodes: DeptTree[] | undefined): Array<{ id: number; deptName: string }> {
  745. if (!nodes?.length) return [];
  746. const list: Array<{ id: number; deptName: string }> = [];
  747. const walk = (items: DeptTree[]) => {
  748. items.forEach((n) => {
  749. if (n.id != null) list.push({ id: n.id, deptName: n.deptName });
  750. if (n.children?.length) walk(n.children);
  751. });
  752. };
  753. walk(nodes);
  754. return list;
  755. }
  756. const deptOptions = computed(() => flattenDeptTree(deptTree.value));
  757. const drawLessonsDeptIdsArrayDept = ref<number[]>([]);
  758. const reviewUserListDept = ref<Array<{ id: number; realname?: string; username?: string }>>([]);
  759. const loadDeptAndUserOptionsDept = async () => {
  760. try {
  761. const [deptRes, userRes] = await Promise.all([
  762. getAllDepartments(),
  763. queryAvailableUserList({ pageNumber: 1, pageSize: 9999, queryParam: {} }),
  764. ]);
  765. const fullTree = (deptRes as DeptTree[]) ?? [];
  766. deptTree.value = Array.isArray(fullTree) && fullTree[0]?.children ? fullTree[0].children : [];
  767. reviewUserListDept.value = (userRes as any)?.records ?? [];
  768. } catch (e) {
  769. console.error('获取部门/用户列表失败:', e);
  770. deptTree.value = [];
  771. reviewUserListDept.value = [];
  772. }
  773. };
  774. const loadRecordList = async () => {
  775. if (!currentId.value) return;
  776. recordTableConfig.loading = true;
  777. try {
  778. const [start, end] = recordDateRange.value && recordDateRange.value.length === 2
  779. ? recordDateRange.value
  780. : ['', ''];
  781. const res = await queryAreaCheckPlanDetailDeptPage(currentId.value, {
  782. pageNumber: recordPagination.pageNumber,
  783. pageSize: recordPagination.pageSize,
  784. queryParam: {
  785. searchKey: recordSearchKeyword.value || undefined,
  786. startDate: start || undefined,
  787. endDate: end || undefined,
  788. id: currentId.value,
  789. },
  790. });
  791. const raw = (res as { data?: { records?: Array<Record<string, unknown>>; totalRow?: number } })?.data ?? res;
  792. const records = raw?.records ?? [];
  793. inspectionRecordList.value = records.map((r: Record<string, unknown>) => ({
  794. ...r,
  795. checkPerson: r.checkPerson ?? r.checkPersonName,
  796. checkedCompany: r.checkedCompany ?? r.checkedCompanyName,
  797. }));
  798. recordPagination.total = raw?.totalRow ?? 0;
  799. } catch (e) {
  800. console.error('查询检查记录失败:', e);
  801. inspectionRecordList.value = [];
  802. recordPagination.total = 0;
  803. } finally {
  804. recordTableConfig.loading = false;
  805. }
  806. };
  807. const handleRecordSizeChange = (value: number) => {
  808. recordPagination.pageSize = value;
  809. recordPagination.pageNumber = 1;
  810. loadRecordList();
  811. };
  812. const handleRecordPageChange = (value: number) => {
  813. recordPagination.pageNumber = value;
  814. loadRecordList();
  815. };
  816. const onRecordSearch = () => {
  817. recordPagination.pageNumber = 1;
  818. loadRecordList();
  819. };
  820. const onRecordExport = async () => {
  821. try {
  822. const response = await exportAreaCheckInspectionRecord(currentId.value);
  823. if (response) {
  824. const fileName = `检查记录_${new Date().toISOString().split('T')[0]}.xlsx`;
  825. downloadByData(response, fileName);
  826. ElMessage.success('导出成功');
  827. }
  828. } catch (e) {
  829. console.error('导出院级文件失败:', e);
  830. ElMessage.error('导出失败,请重试');
  831. }
  832. };
  833. const loadUnqualifiedList = async () => {
  834. if (!currentRecordIdForUnqualified.value) return;
  835. unqualifiedTableConfig.loading = true;
  836. try {
  837. const res = await queryUnqualifiedItemNumDeptPage({
  838. pageNumber: unqualifiedPagination.pageNumber,
  839. pageSize: unqualifiedPagination.pageSize,
  840. queryParam: {
  841. id: currentRecordIdForUnqualified.value,
  842. checkPlace: String(currentRowForUnqualified.value?.checkPlace ?? ''),
  843. checkProblem: String(currentRowForUnqualified.value?.checkProblem ?? ''),
  844. checkTime: String(currentRowForUnqualified.value?.checkTime ?? ''),
  845. },
  846. });
  847. const raw = (res as { data?: { records?: UnqualifiedItemNumRecord[]; totalRow?: number } })?.data ?? res;
  848. unqualifiedList.value = raw?.records ?? [];
  849. unqualifiedPagination.total = raw?.totalRow ?? 0;
  850. } catch (e) {
  851. console.error('查询不合格数据失败:', e);
  852. unqualifiedList.value = [];
  853. unqualifiedPagination.total = 0;
  854. } finally {
  855. unqualifiedTableConfig.loading = false;
  856. }
  857. };
  858. const handleUnqualifiedSizeChange = (value: number) => {
  859. unqualifiedPagination.pageSize = value;
  860. unqualifiedPagination.pageNumber = 1;
  861. loadUnqualifiedList();
  862. };
  863. const handleUnqualifiedPageChange = (value: number) => {
  864. unqualifiedPagination.pageNumber = value;
  865. loadUnqualifiedList();
  866. };
  867. const openUnqualifiedDialog = (row: { id?: number } & Record<string, unknown>) => {
  868. if (!row.id) return;
  869. currentRecordIdForUnqualified.value = Number(row.id);
  870. currentRowForUnqualified.value = row;
  871. unqualifiedPagination.pageNumber = 1;
  872. showUnqualifiedDialog.value = true;
  873. loadUnqualifiedList();
  874. };
  875. const handleSandToHiddenDangerDept = (row: { id?: number } & Record<string, unknown>) => {
  876. if (!row.id) return;
  877. getTableData()
  878. currentRecordIdForUnqualified.value = Number(row.id);
  879. // 部门端入账同样不带入检查记录旧数据,每次打开还原为隐患台账初始表单
  880. Object.assign(sandHiddenDangerFormDataDept, HIDDEN_DANGER_FORM_DATA);
  881. showSandConfirmDialogDept.value = true;
  882. };
  883. const validateSandHiddenDangerFormDept = async () => {
  884. if (!sandHiddenDangerFormRefDept.value) return false;
  885. console.log(sandHiddenDangerFormRefDept.value)
  886. return await sandHiddenDangerFormRefDept.value.validate();
  887. };
  888. const confirmSandToHiddenDangerDept = async () => {
  889. if (!currentRecordIdForUnqualified.value) return;
  890. const valid = await validateSandHiddenDangerFormDept();
  891. if (!valid) return;
  892. sandConfirmLoadingDept.value = true;
  893. try {
  894. const d = sandHiddenDangerFormDataDept;
  895. const payload: SandAreaCheckRecordToHiddenDangerReq = {
  896. areaCheckRecordId: currentRecordIdForUnqualified.value,
  897. sourceType: 4,
  898. sourceRefId: currentRecordIdForUnqualified.value,
  899. dangerProblem: d.dangerProblem || '',
  900. typeId: d.typeId,
  901. reasonId: d.reasonId,
  902. taskSource: d.taskSource || '',
  903. rectificationRequirement: d.rectificationRequirement || '',
  904. rectificationDeadline: d.rectificationDeadline || '',
  905. rectificationDepartmentIds: d.rectificationDepartmentIds || '',
  906. rectificationResponsiblePerson: d.rectificationResponsiblePerson || '',
  907. reviewDepartmentId: d.reviewDepartmentId,
  908. reviewPersonId: d.reviewPersonId,
  909. reviewPersonName: d.reviewPersonName || '',
  910. isDrawLessonsPush: d.isDrawLessonsPush ?? 0,
  911. drawLessonsContent: d.drawLessonsContent || '',
  912. drawLessonsDepartmentIds: d.drawLessonsDepartmentIds || '',
  913. drawLessonsDeadline: d.drawLessonsDeadline || '',
  914. attachments: d.attachments || '',
  915. confirmSandToHiddenDangerDept: d.confirmSandToHiddenDangerDept ?? 0,
  916. rectificationResponsibleIds: d.rectificationResponsibleIds || '',
  917. drawLessonsContent: d.drawLessonsContent || '',
  918. drawLessonsDepartmentIds: d.drawLessonsDepartmentIds || '',
  919. drawLessonsDeadline: d.drawLessonsDeadline || '',
  920. };
  921. await sandAreaCheckRecordToProductionHiddenDanger(payload);
  922. ElMessage.success('入账成功');
  923. // 关闭入账表单弹窗和“不合格数据”弹窗
  924. showSandConfirmDialogDept.value = false;
  925. showUnqualifiedDialog.value = false;
  926. await loadRecordList();
  927. } catch (e) {
  928. console.error('部门端下入账失败:', e);
  929. ElMessage.error(e?.message || e?.data || '下入账失败,请稍后重试');
  930. } finally {
  931. sandConfirmLoadingDept.value = false;
  932. }
  933. };
  934. const onAddRecord = () => {
  935. const needOverallDesc = !viewDetail.value.needOverallDesc ? 0 : 1;
  936. const needSigneeSign = !viewDetail.value.needSigneeSign ? 0 : 1;
  937. router.push({
  938. name: 'areaCheckPlanManagementDeptItem',
  939. query: {
  940. operate: 'area-check-plan-record-add',
  941. planId: currentId.value,
  942. needOverallDesc,
  943. needSigneeSign,
  944. },
  945. });
  946. };
  947. const previewOnlineRef = ref<InstanceType<typeof PreviewOnline>>();
  948. const previewOnline = (url: string | undefined, type: keyof typeof FILE_TYPE_ICON) => {
  949. if (url) previewOnlineRef.value?.open(url, type);
  950. };
  951. const parseSignFiles = (signFile: string | undefined): Array<{ fileUrl: string; fileName: string; fileType: string }> => {
  952. if (!signFile || !String(signFile).trim()) return [];
  953. const parts = String(signFile)
  954. .split(',')
  955. .map((s) => s.trim())
  956. .filter(Boolean);
  957. return parts.map((part) => {
  958. const urlParts = part.split('/');
  959. const fileName = urlParts[urlParts.length - 1] || part || '未知文件';
  960. const extension = fileName.split('.').pop()?.toLowerCase() || '';
  961. let fileType = 'pdf';
  962. if (extension === 'doc' || extension === 'docx') fileType = 'word';
  963. else if (extension === 'xls' || extension === 'xlsx') fileType = 'excel';
  964. else if (extension === 'ppt' || extension === 'pptx') fileType = 'ppt';
  965. return { fileUrl: part, fileName, fileType };
  966. });
  967. };
  968. const onViewRecord = (row: Record<string, unknown>) => {
  969. const needOverallDesc = !viewDetail.value.needOverallDesc ? 0 : 1;
  970. const needSigneeSign = !viewDetail.value.needSigneeSign ? 0 : 1;
  971. router.push({
  972. name: 'areaCheckPlanManagementDeptItem',
  973. query: {
  974. operate: 'area-check-plan-record-view',
  975. recordId: row.id,
  976. planId: currentId.value,
  977. needOverallDesc,
  978. needSigneeSign,
  979. },
  980. });
  981. };
  982. const getDetail = async () => {
  983. if (!currentId.value) return;
  984. try {
  985. const res = await queryAreaCheckPlanManageDeptDetail(currentId.value);
  986. const raw = (res as { data?: unknown })?.data ?? res;
  987. const detail = mapAreaCheckPlanApiRecordToUi(raw);
  988. viewDetailData.value = { ...detail };
  989. loadRecordList();
  990. } catch (e) {
  991. console.error('获取详情失败:', e);
  992. }
  993. };
  994. const cascaderDeptRef = ref<CascaderInstance | null>(null)
  995. const onIssueDeptChange = async () => {
  996. const nodes = cascaderDeptRef.value?.getCheckedNodes()
  997. if (!nodes || nodes.length === 0) return
  998. const currentDept = nodes[0]
  999. sandHiddenDangerFormDataDept.rectificationResponsibleIds = undefined;
  1000. try {
  1001. const userRes = await queryAvailableUserList({ pageNumber: 1, pageSize: 9999, queryParam: {deptName: currentDept.data.deptName||undefined} });
  1002. issueUserList.value = (userRes as any)?.records ?? [];
  1003. } catch (e:any) {
  1004. ElMessage.error(e?.message || e?.data || '加载部门或负责人列表失败');
  1005. issueUserList.value = [];
  1006. }
  1007. };
  1008. onMounted(() => {
  1009. loadDeptAndUserOptionsDept();
  1010. getDetail();
  1011. onIssueDialogOpen();
  1012. });
  1013. </script>
  1014. <style scoped lang="scss">
  1015. @use '@/styles/page-details-layout.scss' as *;
  1016. @use '@/styles/basic-table-file.scss' as *;
  1017. .area-check-plan-view {
  1018. padding: 16px 24px;
  1019. display: flex;
  1020. flex-direction: column;
  1021. gap: 24px;
  1022. }
  1023. .view-section {
  1024. .view-section__title {
  1025. font-weight: 600;
  1026. margin-bottom: 12px;
  1027. display: flex;
  1028. align-items: center;
  1029. gap: 6px;
  1030. &--small {
  1031. font-size: 13px;
  1032. margin-bottom: 8px;
  1033. }
  1034. }
  1035. .view-section__icon {
  1036. width: 4px;
  1037. height: 14px;
  1038. background: var(--el-color-primary);
  1039. border-radius: 2px;
  1040. }
  1041. }
  1042. .view-summary {
  1043. .view-summary__title {
  1044. font-weight: 600;
  1045. font-size: 15px;
  1046. margin-bottom: 4px;
  1047. }
  1048. .view-summary__venue {
  1049. margin-bottom: 8px;
  1050. }
  1051. .view-summary__meta {
  1052. font-size: 13px;
  1053. color: var(--el-text-color-secondary);
  1054. span + span {
  1055. margin-left: 16px;
  1056. }
  1057. }
  1058. }
  1059. .audit-content {
  1060. .section-title {
  1061. display: flex;
  1062. align-items: center;
  1063. gap: 8px;
  1064. margin: 20px 0 12px 0;
  1065. font-size: 16px;
  1066. font-weight: 600;
  1067. color: #333;
  1068. .section-title__icon {
  1069. font-size: 18px;
  1070. color: #333;
  1071. }
  1072. }
  1073. .section-title:first-child {
  1074. margin-top: 0;
  1075. }
  1076. .detail-ct {
  1077. font-size: 14px;
  1078. margin-bottom: 20px;
  1079. &--table {
  1080. border: 1px solid #dcdfe6;
  1081. .row {
  1082. display: flex;
  1083. border-bottom: 1px solid #dcdfe6;
  1084. &:last-child {
  1085. border-bottom: none;
  1086. }
  1087. }
  1088. .col {
  1089. display: flex;
  1090. flex: 1;
  1091. min-height: 40px;
  1092. align-items: stretch;
  1093. .label {
  1094. display: flex;
  1095. align-items: center;
  1096. justify-content: flex-end;
  1097. flex-shrink: 0;
  1098. width: 260px;
  1099. padding: 0 12px;
  1100. background-color: #f5f5f5;
  1101. border-right: 1px solid #dcdfe6;
  1102. color: #333;
  1103. }
  1104. .value {
  1105. flex: 1;
  1106. display: flex;
  1107. align-items: center;
  1108. padding: 10px 20px;
  1109. background-color: #fff;
  1110. border-right: 1px solid #dcdfe6;
  1111. color: #333;
  1112. &--list {
  1113. align-items: flex-start;
  1114. .inspection-content-list {
  1115. margin: 0;
  1116. padding-left: 20px;
  1117. line-height: 1.8;
  1118. color: #333;
  1119. }
  1120. }
  1121. }
  1122. }
  1123. .row .col:last-child .value {
  1124. border-right: none;
  1125. }
  1126. .row .col:nth-child(2) .label {
  1127. border-left: 1px solid #dcdfe6;
  1128. }
  1129. }
  1130. }
  1131. }
  1132. .view-record-toolbar {
  1133. margin-bottom: 12px;
  1134. display: flex;
  1135. align-items: center;
  1136. flex-wrap: wrap;
  1137. gap: 8px;
  1138. }
  1139. .view-record-table {
  1140. margin-bottom: 16px;
  1141. }
  1142. .view-record-toolbar-btn{
  1143. margin-left: auto;
  1144. }
  1145. </style>