indexPipeTab.vue 40 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349
  1. <template>
  2. <ContentWrap>
  3. <el-form
  4. class="-mb-15px"
  5. :model="searchInfo"
  6. ref="queryFormRef"
  7. :inline="true"
  8. label-width="140px"
  9. >
  10. <el-form-item label="任务单号" prop="orderNo">
  11. <el-input
  12. v-model="searchInfo.orderNo"
  13. placeholder="请输入任务单号"
  14. clearable
  15. @keyup.enter="getList"
  16. class="!w-200px"
  17. />
  18. </el-form-item>
  19. <el-form-item label="工程号" prop="equipCode">
  20. <el-input
  21. v-model="searchInfo.equipCode"
  22. placeholder="请输入工程号"
  23. clearable
  24. @keyup.enter="getList"
  25. class="!w-200px"
  26. />
  27. </el-form-item>
  28. <el-form-item label="使用单位" prop="unitName">
  29. <el-input
  30. v-model="searchInfo.unitName"
  31. placeholder="请输入使用单位"
  32. clearable
  33. @keyup.enter="getList"
  34. class="!w-200px"
  35. />
  36. </el-form-item>
  37. <el-form-item label="检验性质" prop="checkType">
  38. <el-select
  39. v-model="searchInfo.checkType"
  40. placeholder="请选择检验性质"
  41. clearable
  42. class="!w-200px"
  43. >
  44. <el-option
  45. v-for="(item, key) in PressurePipeCheckTypeMap"
  46. :key="key"
  47. :label="item"
  48. :value="key"
  49. />
  50. </el-select>
  51. </el-form-item>
  52. <el-form-item label="设备类别" prop="equipType">
  53. <el-select
  54. v-model="searchInfo.equipType"
  55. placeholder="请选择设备类别"
  56. clearable
  57. class="!w-200px"
  58. >
  59. <el-option
  60. v-for="(item) in equipmentTypeMap"
  61. :key="item.value"
  62. :label="item.label"
  63. :value="item.value"
  64. />
  65. </el-select>
  66. </el-form-item>
  67. <el-form-item label="检验时间" prop="checkDate">
  68. <el-date-picker
  69. v-model="searchInfo.checkDate"
  70. value-format="YYYY-MM-DD HH:mm:ss"
  71. type="daterange"
  72. start-placeholder="开始日期"
  73. end-placeholder="结束日期"
  74. :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
  75. class="!w-200px"
  76. />
  77. </el-form-item>
  78. <el-form-item label="检验员" prop="checkUserIds">
  79. <CustomUserSelectModal
  80. class="!w-200px"
  81. v-model="searchInfo.checkUserIds"
  82. :multiple="true"
  83. :collapse-tags="true"
  84. :collapse-tags-tooltip="true"
  85. clearable
  86. placeholder="请选择"
  87. />
  88. </el-form-item>
  89. <el-form-item label="接收人姓名" prop="recipient">
  90. <el-input
  91. v-model="searchInfo.recipient"
  92. placeholder="请输入接收人姓名"
  93. clearable
  94. @keyup.enter="getList"
  95. class="!w-200px"
  96. />
  97. </el-form-item>
  98. <el-form-item label="接收人手机号" prop="recipientPhone">
  99. <el-input
  100. v-model="searchInfo.recipientPhone"
  101. placeholder="请输入接收人手机号"
  102. clearable
  103. @keyup.enter="getList"
  104. class="!w-200px"
  105. />
  106. </el-form-item>
  107. <!-- <el-form-item label="剩余期限" prop="remainingDays">
  108. <el-input
  109. v-model="searchInfo.remainingDays"
  110. placeholder="请输入剩余期限"
  111. clearable
  112. @keyup.enter="getList"
  113. class="!w-200px"
  114. />
  115. </el-form-item> -->
  116. <el-form-item label="客户剩余期限" prop="remainingDays">
  117. <el-select
  118. v-model="searchInfo.isOverdue"
  119. placeholder="请选择客户剩余期限"
  120. clearable
  121. class="!w-200px"
  122. >
  123. <el-option label="未超期" :value="false" />
  124. <el-option label="已超期" :value="true" />
  125. </el-select>
  126. </el-form-item>
  127. <el-form-item label="所属部门" prop="deptId">
  128. <el-select v-model="searchInfo.deptId" placeholder="请选择所属部门" class="!w-200px">
  129. <el-option
  130. v-for="item in deptDataList"
  131. :key="item.id"
  132. :label="item.name"
  133. :value="item.id"
  134. />
  135. </el-select>
  136. </el-form-item>
  137. <el-form-item label="意见书经办人" prop="handlerIdList">
  138. <CustomUserSelectModal
  139. v-model="searchInfo.handlerId"
  140. :collapseTags="true"
  141. :collapseTagsTooltip="true"
  142. :multiple="false"
  143. placeholder="请选择用户"
  144. clearable
  145. class="!w-200px"
  146. />
  147. </el-form-item>
  148. <el-form-item label="检验通知书状态" prop="rectificationStatusList">
  149. <el-select
  150. v-model="searchInfo.rectificationStatusList"
  151. placeholder="请选择检验通知书状态"
  152. clearable
  153. multiple
  154. collapse-tags
  155. collapse-tags-tooltip
  156. class="!w-200px"
  157. >
  158. <el-option
  159. v-for="(item, key) in rectificationStatusMap"
  160. :key="key"
  161. :label="item"
  162. :value="key"
  163. />
  164. </el-select>
  165. </el-form-item>
  166. <el-form-item label="公众号推送客户状态" prop="mpSendStatusList">
  167. <el-select
  168. v-model="searchInfo.mpSendStatusList"
  169. placeholder="请选择任务状态"
  170. clearable
  171. multiple
  172. collapse-tags
  173. collapse-tags-tooltip
  174. class="!w-200px"
  175. >
  176. <el-option v-for="(item, key) in mpSendStatusMap" :key="key" :label="item" :value="key" />
  177. </el-select>
  178. </el-form-item>
  179. <el-form-item label="出具月份" prop="ratifyMonth">
  180. <el-date-picker
  181. v-model="searchInfo.ratifyMonth"
  182. type="month"
  183. value-format="YYYY-MM"
  184. placeholder="选择月份"
  185. clearable
  186. class="!w-200px"
  187. />
  188. </el-form-item>
  189. <el-form-item>
  190. <el-button @click="search(1)"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
  191. <el-button @click="search(2)"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
  192. </el-form-item>
  193. </el-form>
  194. </ContentWrap>
  195. <ContentWrap>
  196. <div class="toolBox">
  197. <el-button type="primary" plain @click="handleExport" :loading="exportLoading">
  198. <Icon icon="ep:download" class="mr-5px" /> 导出
  199. </el-button>
  200. <el-button type="primary" plain @click="batchRePush" :disabled="disabled">
  201. 批量消息推送
  202. </el-button>
  203. </div>
  204. <!-- <el-radio-group class="mb-[10px]" v-model="tableStatus" @change="handleRadioChange">
  205. <el-radio-button label="全部" value="" />
  206. <el-radio-button label="未发送" value="1" />
  207. <el-radio-button label="发送失败" value="2" />
  208. <el-radio-button label="已超期" value="3" />
  209. </el-radio-group> -->
  210. <el-table ref="tableRef" :data="dataSource" :stripe="true" border height="calc(100vh - 500px)">
  211. <el-table-column type="selection" width="55" fixed="left" />
  212. <el-table-column label="操作" align="center" min-width="300" fixed="left">
  213. <template #default="{ row }">
  214. <div class="flex justify-center">
  215. <!-- <el-button link type="primary" v-if="filerFileUrlShowFn(row)" @click="handleFilePreview(row)"> 查看附件 </el-button>-->
  216. <el-button link type="primary" @click="handleRePush(row)"> 消息推送 </el-button>
  217. <el-button link type="primary" @click="() => handleFollowRecord(row)">
  218. 跟进记录
  219. </el-button>
  220. <el-button
  221. link
  222. type="primary"
  223. @click="() => handleRowDownload(row)"
  224. :disabled="disabled"
  225. >
  226. 下载意见书
  227. </el-button>
  228. </div>
  229. </template>
  230. </el-table-column>
  231. <el-table-column label="检验通知书状态" align="center" min-width="150px">
  232. <template #default="scope">
  233. {{ rectificationStatusMap[scope.row.rectificationStatus] }}
  234. </template>
  235. </el-table-column>
  236. <el-table-column label="意见书编号" align="center" prop="reportedNo" width="150px" />
  237. <el-table-column
  238. label="使用单位"
  239. align="center"
  240. prop="unitName"
  241. min-width="150px"
  242. show-overflow-tooltip
  243. >
  244. <template #default="{row}">
  245. <div style="color: #015293; cursor: pointer; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;" @click="handleUnitCodeFn(row.unitCode)">{{row.unitName}}</div>
  246. </template>
  247. </el-table-column>
  248. <el-table-column label="回收截止时间" align="center" prop="recycleExpireDate" min-width="170">
  249. <template #default="{ row }">
  250. {{ formatDate(row.recycleExpireDate,'YYYY-MM-DD') }}
  251. </template>
  252. </el-table-column>
  253. <el-table-column label="接收人姓名" align="center" prop="recipient" min-width="150px">
  254. <template #default="scope">
  255. {{ scope.row.recipient || '-' }}
  256. </template>
  257. </el-table-column>
  258. <el-table-column label="接收人手机号" align="center" prop="recipientPhone" min-width="150px">
  259. <template #default="scope">
  260. {{ scope.row.recipientPhone || '-' }}
  261. </template>
  262. </el-table-column>
  263. <el-table-column label="跟进记录手机号" align="center" prop="followRecordReceiverPhone" min-width="150px">
  264. <template #default="scope">
  265. {{ scope.row.followRecordReceiverPhone || '-' }}
  266. </template>
  267. </el-table-column>
  268. <!-- <el-table-column
  269. label="详细信息"
  270. align="center"
  271. prop="detailedInfo"
  272. min-width="150px"
  273. show-overflow-tooltip
  274. >
  275. <template #default="{ row }">
  276. <span class="cursor-pointer" @click="handleUpdateRow(row)">{{
  277. row.detailedInfo || '-'
  278. }}</span>
  279. </template>
  280. </el-table-column> -->
  281. <el-table-column
  282. label="发送方式"
  283. align="center"
  284. prop="distributionMethod"
  285. min-width="150px"
  286. show-overflow-tooltip
  287. />
  288. <el-table-column label="发送时间" align="center" prop="sendTime" min-width="170">
  289. <template #default="{ row }">
  290. {{ formatDate(row.sendTime) }}
  291. </template>
  292. </el-table-column>
  293. <el-table-column label="确认接收时间" align="center" prop="signTime" min-width="150px">
  294. <template #default="{ row }">
  295. {{ formatDate(row.signTime) }}
  296. </template>
  297. </el-table-column>
  298. <el-table-column label="回收时间" align="center" prop="rectificationTime" min-width="170">
  299. <template #default="{ row }">
  300. {{ formatDate(row.rectificationTime) }}
  301. </template>
  302. </el-table-column>
  303. <el-table-column label="检验员" align="center" prop="checkUsers" min-width="200">
  304. <template #default="scope">
  305. <div v-if="scope.row.checkUsers && scope.row.checkUsers.length > 0">
  306. <div v-for="user in scope.row.checkUsers" :key="user.id">
  307. {{ `${user.nickname}(${user.employeeNo})` }}
  308. </div>
  309. </div>
  310. <div v-else></div>
  311. </template>
  312. </el-table-column>
  313. <el-table-column
  314. align="center"
  315. label="客户剩余确认时间(天)"
  316. prop="confirmationTimeStr"
  317. min-width="190"
  318. >
  319. <template #default="{ row }">
  320. {{ row.rectificationStatus !== 0 ? '-' : row.confirmationTimeStr || '-' }}
  321. </template>
  322. </el-table-column>
  323. <el-table-column label="区域" align="center" prop="equipDistrictName" width="150px" />
  324. <el-table-column
  325. label="公众号推送客户状态"
  326. align="center"
  327. prop="mpSendStatus"
  328. min-width="155"
  329. >
  330. <template #default="{ row }">
  331. {{ mpSendStatusMap[row.mpSendStatus] || '-' }}
  332. </template>
  333. </el-table-column>
  334. <el-table-column label="任务单号" align="center" prop="orderNo" min-width="150px" />
  335. <el-table-column label="工程号" align="center" prop="equipCode" min-width="270">
  336. <template #default="{ row }">
  337. <div>
  338. {{ row.equipCode }}
  339. <el-tag v-if="row.productNo" type="success">
  340. {{ row.productNo }}
  341. </el-tag>
  342. </div>
  343. </template>
  344. </el-table-column>
  345. <el-table-column label="使用证编号" align="center" prop="useRegisterNo" min-width="120" />
  346. <el-table-column
  347. label="设备类别"
  348. align="center"
  349. prop="equipmentType"
  350. min-width="150px"
  351. show-overflow-tooltip
  352. >
  353. <template #default="{ row }">
  354. {{ equipmentTypeMap.find((item) => item.value == row.equipmentType)?.label || '-' }}
  355. </template>
  356. </el-table-column>
  357. <el-table-column label="检验性质" align="center" prop="checkType" min-width="120px">
  358. <template #default="scope">
  359. {{ PressurePipeCheckTypeMap[scope.row.checkType] }}
  360. </template>
  361. </el-table-column>
  362. <el-table-column label="检验时间" align="center" prop="checkDate" min-width="120px">
  363. <template #default="{ row }">
  364. {{ formatArrayDate(row.checkDate) }}
  365. </template>
  366. </el-table-column>
  367. <el-table-column label="审批通过日期" align="center" prop="ratifyTime" min-width="120px">
  368. <template #default="{ row }">
  369. {{ formatDate(row.ratifyTime, "YYYY-MM-DD") }}
  370. </template>
  371. </el-table-column>
  372. <!-- <el-table-column
  373. label="剩余回收时间"
  374. align="center"
  375. prop="remainingRecoveryTimeStr"
  376. min-width="120px"
  377. /> -->
  378. <el-table-column label="所属部门" align="center" prop="deptName" min-width="180" />
  379. <el-table-column label="意见书经办人" align="center" prop="handlerInfoList" min-width="200">
  380. <template #default="{ row }">
  381. {{ row.handlerUserList?.map((item: Recordable) => item.nickname).join('/') || '' }}
  382. </template>
  383. </el-table-column>
  384. </el-table>
  385. <!-- 分页 -->
  386. <Pagination
  387. :total="pagination.total"
  388. v-model:page="pagination.pageNo"
  389. v-model:limit="pagination.pageSize"
  390. @pagination="getList"
  391. />
  392. </ContentWrap>
  393. <!-- 单个重新推送和批量重新推送 -->
  394. <el-dialog
  395. v-if="recipientDialogVisible"
  396. :title="recipientType === 'single' ? '重新推送' : '批量重新推送'"
  397. v-model="recipientDialogVisible"
  398. width="40%"
  399. :before-close="handleClose"
  400. >
  401. <ContentWrap>
  402. <el-form
  403. ref="recipientFormRef"
  404. :model="recipientFormData"
  405. :rules="recipientFormRules"
  406. label-width="140px"
  407. :validate-on-rule-change="false"
  408. >
  409. <el-form-item label="接收人名称:" prop="recipient">
  410. <el-input
  411. v-model="recipientFormData.recipient"
  412. placeholder="请输入接收人名称"
  413. class="!w-300px"
  414. />
  415. </el-form-item>
  416. <el-form-item label="接收人手机号码:" prop="recipientPhone">
  417. <el-input
  418. v-model="recipientFormData.recipientPhone"
  419. placeholder="请输入接收人手机号码"
  420. class="!w-300px"
  421. />
  422. </el-form-item>
  423. </el-form>
  424. </ContentWrap>
  425. <template #footer>
  426. <el-button @click="handleClose">取消</el-button>
  427. <el-button type="primary" :loading="submitting" @click="submitForm">提交</el-button>
  428. </template>
  429. </el-dialog>
  430. <!-- 预览查看下载报告 -->
  431. <CustomDialog
  432. v-model="showReportDialog"
  433. lock-scroll
  434. align-center
  435. :show-footer="false"
  436. width="1000px"
  437. top="0"
  438. class="h-[95vh] overflow-hidden"
  439. @cancel="handleCancel"
  440. >
  441. <el-button type="primary" v-if="isCanDownload" :disabled="!reportSource" @click="handleDownload"
  442. >下载</el-button
  443. >
  444. <el-scrollbar always noresize max-height="calc(95vh - 48px)">
  445. <VuePdfEmbed
  446. v-if="showReportDialog"
  447. v-loading="pdfLoading"
  448. :width="968"
  449. :source="reportSource"
  450. @rendered="handlePdfRendered"
  451. />
  452. </el-scrollbar>
  453. </CustomDialog>
  454. <ReportListUploadModal
  455. ref="reportListUploadModalRef"
  456. :flag="true"
  457. :selectedItem="currentReport"
  458. :reportList="allReportList"
  459. />
  460. <Dialog
  461. v-if="followRecordRespFlag"
  462. :close-on-click-modal="false"
  463. v-model:modelValue="followRecordRespFlag"
  464. title="跟进记录"
  465. width="70%"
  466. :showCancel="false"
  467. :showFooter="false"
  468. :dialogAttrs="{ showClose: false }"
  469. @close="handleCloseFollowRecordRespDialog"
  470. >
  471. <section v-loading="recordLoading">
  472. <SmartTable
  473. ref="followRecordRespTableRef"
  474. v-model:pageNo="followRecordRespTableParams.pageNo"
  475. v-model:pageSize="followRecordRespTableParams.pageSize"
  476. v-model:total="followRecordRespTableParams.total"
  477. :columns="getFollowRecordRespColumns"
  478. :data="followRecordRespList"
  479. :useBorderLayout="false"
  480. :showRefresh="false"
  481. :buttons="[]"
  482. height="450px"
  483. :page-sizes="[10, 20, 50, 100]"
  484. @on-page-no-change="() => followRecordRespTablePage()"
  485. @on-page-size-change="() => followRecordRespTablePage()"
  486. />
  487. <div class="flex gap-10px mt-10px" style="width: 100%">
  488. <div class="!w-[70px] flex items-center justify-end">类 型:</div>
  489. <div class="flex-1">
  490. <el-radio-group
  491. v-model="followParams.type"
  492. style="width: 100%"
  493. @change="handleFollowTypeChange"
  494. >
  495. <el-radio v-for="item in getFollowTypeList" :key="item.value" :value="item.value">
  496. {{ item.label }}
  497. </el-radio>
  498. </el-radio-group>
  499. </div>
  500. </div>
  501. <div v-if="followParams.type === 3" class="flex gap-10px mt-10px" style="width: 100%">
  502. <div class="!w-[90px] flex items-center justify-end">发送方式:</div>
  503. <div class="flex-1">
  504. <el-input
  505. v-model="followParams.distributionMethod"
  506. style="width: 100%"
  507. placeholder="请输入发送方式"
  508. show-word-limit
  509. :maxlength="20"
  510. />
  511. </div>
  512. </div>
  513. <div v-if="followParams.type === 3" class="flex gap-10px mt-10px" style="width: 100%">
  514. <div class="!w-[90px] flex items-center justify-end">接收人姓名:</div>
  515. <div class="flex-1">
  516. <el-input
  517. v-model="followParams.receiver"
  518. style="width: 100%"
  519. placeholder="请输入接收人姓名"
  520. show-word-limit
  521. :maxlength="20"
  522. />
  523. </div>
  524. </div>
  525. <div v-if="followParams.type === 3" class="flex gap-10px mt-10px" style="width: 100%">
  526. <div class="!w-[90px] flex items-center justify-end">接收人电话:</div>
  527. <div class="flex-1">
  528. <el-input
  529. v-model="followParams.receiverPhone"
  530. style="width: 100%"
  531. placeholder="请输入接收人电话"
  532. show-word-limit
  533. />
  534. </div>
  535. </div>
  536. <div v-if="followParams.type === 3" class="flex gap-10px mt-10px" style="width: 100%">
  537. <div class="!w-[90px] flex items-center justify-end">确认接收时间:</div>
  538. <div class="flex-1">
  539. <el-date-picker
  540. v-model="followParams.receiveConfirmTime"
  541. type="datetime"
  542. placeholder="选择时间"
  543. format="YYYY-MM-DD HH:mm:ss"
  544. value-format="x"
  545. />
  546. </div>
  547. </div>
  548. <div class="flex gap-10px mt-10px" style="width: 100%">
  549. <div class="!w-[90px] flex items-center justify-end">发送时间:</div>
  550. <div class="flex-1">
  551. <!-- 嵌入的时间选择器 -->
  552. <el-date-picker
  553. v-model="followParams.followTime"
  554. type="datetime"
  555. :disabled="[1, 4].includes(followParams.type)"
  556. placeholder="选择时间"
  557. format="YYYY-MM-DD HH:mm:ss"
  558. value-format="x"
  559. />
  560. </div>
  561. </div>
  562. <div class="flex gap-10px mt-10px" style="width: 100%">
  563. <div class="!w-[90px] text-right">跟进记录:</div>
  564. <div class="flex-1">
  565. <div class="flex-1">
  566. <div
  567. style="
  568. border: 1px solid #dcdfe6;
  569. border-radius: 4px;
  570. padding: 10px;
  571. display: flex;
  572. flex-direction: column;
  573. gap: 10px;
  574. "
  575. >
  576. <!-- 模拟的 textarea 输入框 -->
  577. <el-input
  578. v-model="followParams.remark"
  579. type="textarea"
  580. :maxlength="300"
  581. show-word-limit
  582. :rows="7"
  583. placeholder="请输入内容"
  584. style="
  585. width: 100%;
  586. border: none;
  587. resize: vertical;
  588. outline: none;
  589. font-family: inherit;
  590. "
  591. />
  592. <div
  593. style="
  594. width: 100%;
  595. display: flex;
  596. justify-content: space-between;
  597. align-items: center;
  598. "
  599. >
  600. <div
  601. >跟进人:<el-tag
  602. >{{ userStore.getUser.nickname }}{{ userStore.getUser.employeeNo }}</el-tag
  603. ></div
  604. >
  605. </div>
  606. </div>
  607. </div>
  608. </div>
  609. </div>
  610. <div class="dialog-footer">
  611. <el-button type="primary" @click="handleFollowRecordRespConfirm">保存</el-button>
  612. <el-button type="default" @click="followRecordRespFlag = false">取消</el-button>
  613. </div>
  614. </section>
  615. </Dialog>
  616. <Dialog
  617. :close-on-click-modal="false"
  618. v-model:modelValue="updateDialogVisible"
  619. title="更新详细信息"
  620. width="60%"
  621. :showCancel="false"
  622. :showFooter="false"
  623. :dialogAttrs="{ showClose: false }"
  624. @close="handleCloseUpdateDialog"
  625. >
  626. <section v-loading="recordLoading">
  627. <el-form
  628. ref="updateFormRef"
  629. :model="updateFormData"
  630. :rules="updateFormRules"
  631. label-width="100px"
  632. :validate-on-rule-change="false"
  633. >
  634. <el-form-item label="详细信息:" prop="detailedInfo">
  635. <el-input
  636. v-model="updateFormData.detailedInfo"
  637. placeholder="请输入详细信息"
  638. type="textarea"
  639. :rows="7"
  640. show-word-limit
  641. maxlength="300"
  642. class="!w-full"
  643. />
  644. </el-form-item>
  645. </el-form>
  646. <div class="dialog-footer">
  647. <el-button type="primary" @click="handleUpdateFollowRecordRespConfirm">保存</el-button>
  648. <el-button type="default" @click="handleCloseUpdateDialog">取消</el-button>
  649. </div>
  650. </section>
  651. </Dialog>
  652. <unitContainerForm ref="unitContainerFormRef" />
  653. <!-- PDF预览 + 消息推送弹窗 -->
  654. <FilePreview
  655. v-if="previewVisible"
  656. v-model="previewVisible"
  657. :id="currentPreviewId"
  658. :reportId="currentReportId"
  659. :filename="currentFilename"
  660. :title="'检验意见通知书'"
  661. @close="handlePreviewClose"
  662. @sbmit="fiePreviewEmitFn"
  663. />
  664. </template>
  665. <script setup lang="ts">
  666. import { ref, reactive } from 'vue'
  667. import VuePdfEmbed from 'vue-pdf-embed'
  668. import {PressurePipeCheckTypeMap} from '@/utils/constants'
  669. import unitContainerForm from '@/components/unitContainerForm/index.vue'
  670. import { formatArrayDate, formatDate } from '@/utils/formatTime'
  671. import { ElMessage, FormRules, ElForm, FormInstance } from 'element-plus'
  672. import ReportListUploadModal from '@/views/pressure/checker/components/reportListUploadModal.vue'
  673. import { PipeTaskOrderApi, PipeTaskOrderOrderItemVO } from '@/api/pressure2/pipetaskorder'
  674. import { getDeptList } from '@/api/laboratory/dept'
  675. import CustomUserSelectModal from '@/components/SmartTable/components/selectUserModal.vue'
  676. import SmartTable from '@/components/SmartTable/SmartTable'
  677. import { usePageLoading } from '@/hooks/web/usePageLoading'
  678. import FilePreview from './component/FilePreview.vue'
  679. import { useRoute } from 'vue-router'
  680. import {DICT_TYPE, getStrDictOptions} from '@/utils/dict'
  681. const route = useRoute()
  682. const { loadStart, loadDone } = usePageLoading()
  683. const reportListUploadModalRef = ref<InstanceType<typeof ReportListUploadModal>>()
  684. const unitContainerFormRef = ref<InstanceType<typeof unitContainerForm>>()
  685. const userStore = useUserStoreWithOut() // 用户信息缓存
  686. const equipmentTypeMap = getStrDictOptions(DICT_TYPE.PIPE_TYPE)
  687. import dayJs from 'dayjs'
  688. import download from '@/utils/download'
  689. import { cloneDeep } from 'lodash-es'
  690. import { useUserStoreWithOut } from '@/store/modules/user'
  691. import { buildFileUrl } from '@/utils'
  692. import {PipeInputApi} from "@/api/pressure2/pipeInput";
  693. const currentPreviewId = ref<string>('')
  694. const currentFilename = ref<string>('')
  695. const previewVisible = ref<boolean>(false)
  696. const currentReportId = ref<string>('')
  697. const message = useMessage() // 消息弹窗
  698. const currentReport = ref<any>({})
  699. // 表单数据
  700. const recipientRow = ref<Record<string, any>>({})
  701. const recipientType = ref<'single' | 'batch'>()
  702. const recipientFormRef = ref<InstanceType<typeof ElForm>>()
  703. const allReportList = ref<any>([])
  704. const recipientFormData = reactive<any>({
  705. recipient: '',
  706. recipientPhone: ''
  707. })
  708. // 表单验证规则 - 只在提交时验证,不设置实时验证触发器
  709. const recipientFormRules = ref<FormRules<any>>({
  710. recipient: [{ required: true, message: '请输入接收人名称' }],
  711. recipientPhone: [
  712. { required: true, message: '请输入接收人手机号码' },
  713. { type: 'pattern', pattern: /^1[3-9]\d{9}$/, message: '请输入正确的接收人手机号码' }
  714. ]
  715. })
  716. const recipientDialogVisible = ref(false)
  717. const submitting = ref(false)
  718. const submitForm = async () => {
  719. const subFormValid = await recipientFormRef.value?.validate()
  720. if (!subFormValid) {
  721. ElMessage.warning('请填写完整的表单信息')
  722. return
  723. }
  724. submitting.value = true
  725. let fetchApi
  726. let params
  727. if (recipientType.value === 'single') {
  728. params = {
  729. ...recipientFormData,
  730. id: recipientRow.value.reportId
  731. }
  732. fetchApi = PipeTaskOrderApi.inspectionOpinionSend
  733. } else {
  734. const list = tableRef.value.getSelectionRows()
  735. params = list.map((item) => ({
  736. id: item.reportId,
  737. ...recipientFormData
  738. }))
  739. fetchApi = PipeTaskOrderApi.inspectionOpinionSendBatch
  740. }
  741. try {
  742. await fetchApi(params)
  743. ElMessage.success(recipientType.value === 'single' ? '重新推送成功' : '批量重新推送成功')
  744. handleClose()
  745. handlePreviewClose()
  746. getList()
  747. } finally {
  748. submitting.value = false
  749. }
  750. }
  751. // 关闭对话框
  752. const handleClose = () => {
  753. recipientDialogVisible.value = false
  754. recipientRow.value = {}
  755. recipientFormRef.value?.resetFields()
  756. }
  757. const rectificationStatusMap = reactive({
  758. 0: '待确认',
  759. 1: '待整改',
  760. 2: '已提交',
  761. 3: '材料有误',
  762. 4: '整改通过',
  763. 5: '整改不通过'
  764. })
  765. const mpSendStatusMap = reactive({
  766. '0': '成功',
  767. '1': '拒绝接收',
  768. '2': '其他原因失败',
  769. '3': '发送失败',
  770. '4': '未发送'
  771. })
  772. const queryFormRef = ref<FormInstance>()
  773. const searchInfo = ref({
  774. handlerId: userStore.getUser.id,
  775. // rectificationStatusList: ['0']
  776. }) as any
  777. const dataSource = ref<PipeTaskOrderOrderItemVO[]>([]) // 列表数据源
  778. const pagination = ref({
  779. pageNo: 1,
  780. pageSize: 20,
  781. total: 0
  782. })
  783. const tableRef = ref(null) as any
  784. // 获取部门数据
  785. const deptDataList = ref<any>([]) // 部门数据
  786. const getDeptDataList = async () => {
  787. const res = await getDeptList({ pageNo: 1, pageSize: 1000 })
  788. deptDataList.value = res || []
  789. }
  790. /**
  791. * 获取列表数据
  792. */
  793. const getList = async () => {
  794. // getReportCountData()
  795. loadStart()
  796. try {
  797. const params: any = cloneDeep({
  798. ...searchInfo.value,
  799. orderByType: 2,
  800. pageNo: pagination.value.pageNo,
  801. pageSize: pagination.value.pageSize
  802. })
  803. // 出具月份转换
  804. if (params.ratifyMonth) {
  805. const [y, m] = params.ratifyMonth.split('-')
  806. params.ratifyTimeStart = `${y}-${m}-01 00:00:00`
  807. const lastDay = new Date(Number(y), Number(m), 0).getDate()
  808. params.ratifyTimeEnd = `${y}-${m}-${String(lastDay).padStart(2, '0')} 23:59:59`
  809. delete params.ratifyMonth
  810. }
  811. if (!params.tableStatus) delete params.tableStatus
  812. const res = await PipeTaskOrderApi.getCheckBookList(params)
  813. dataSource.value = res?.list || []
  814. pagination.value.total = res?.total || 0
  815. } catch (error) {
  816. dataSource.value = []
  817. pagination.value.total = 0
  818. ElMessage.error('获取列表数据失败')
  819. } finally {
  820. loadDone()
  821. }
  822. }
  823. /**
  824. * 搜索、重置
  825. * @param type 1 搜索 2重置
  826. */
  827. const search = (type: number) => {
  828. if (type == 2) {
  829. tableStatus.value = ''
  830. // queryFormRef.value?.resetFields()
  831. searchInfo.value = {
  832. handlerId: userStore.getUser.id
  833. }
  834. }
  835. getList()
  836. }
  837. const showReportDialog = ref(false)
  838. const pdfLoading = ref(false)
  839. const reportSource = ref('')
  840. const handlePdfRendered = () => {
  841. pdfLoading.value = false
  842. }
  843. const handleCancel = () => {
  844. isCanDownload.value = false
  845. reportSource.value = ''
  846. }
  847. const isCanDownload = ref(false)
  848. const handleDownload = () => {
  849. reportSource.value && window.open(reportSource.value, '_blank')
  850. }
  851. /**
  852. * 批量重新推送
  853. */
  854. const batchRePush = async () => {
  855. const list = tableRef.value.getSelectionRows()
  856. if (!list.length) {
  857. ElMessage.warning('请选择数据进行操作!')
  858. return
  859. }
  860. recipientType.value = 'batch'
  861. recipientDialogVisible.value = true
  862. }
  863. /**
  864. * 重新推送
  865. */
  866. const handleRePush = async (row) => {
  867. recipientRow.value = row
  868. recipientType.value = 'single'
  869. currentReportId.value = row.opinionReportedUrl
  870. currentPreviewId.value = row.id
  871. currentFilename.value = '检验意见通知书.pdf'
  872. // 重置上次推送的接收人信息
  873. recipientFormData.recipient = ''
  874. recipientFormData.recipientPhone = ''
  875. previewVisible.value = true
  876. }
  877. const fiePreviewEmitFn = async () => {
  878. try {
  879. recipientFormData.recipient = (recipientRow.value as any).recipient || (recipientRow.value as any).defaultRecipient || ''
  880. recipientFormData.recipientPhone = (recipientRow.value as any).recipientPhone || (recipientRow.value as any).defaultRecipientPhone || ''
  881. } catch (e) {
  882. console.warn('获取推送接收人信息失败,使用默认值', e)
  883. }
  884. // 兜底使用行数据中的默认值
  885. if (!recipientFormData.recipient) {
  886. recipientFormData.recipient = (recipientRow.value as any).defaultRecipient || ''
  887. recipientFormData.recipientPhone = (recipientRow.value as any).defaultRecipientPhone || ''
  888. }
  889. recipientDialogVisible.value = true
  890. }
  891. const handleFilePreview = (row) => {
  892. currentReport.value = row
  893. allReportList.value = [{id: row.id, reportName: row.reportName}]
  894. reportListUploadModalRef.value?.openModal(false, currentReport.value)
  895. }
  896. const filerFileUrlShowFn = (row) => {
  897. if (row?.attachment || row?.image || row?.video) {
  898. return true
  899. }else {
  900. return false
  901. }
  902. }
  903. // 存储展开状态的响应式数据
  904. // 判断行是否展开
  905. // 切换展开状态
  906. const disabled = ref(false)
  907. const exportLoading = ref(false)
  908. /**
  909. * 导出
  910. */
  911. const handleExport = async () => {
  912. const list = tableRef.value.getSelectionRows()
  913. if (!list.length) {
  914. ElMessage.warning('请选择数据进行操作!')
  915. return
  916. }
  917. const confirm = await message.exportConfirm().catch(() => false)
  918. if (!confirm) return
  919. try {
  920. exportLoading.value = true
  921. loadStart()
  922. const params = {
  923. ...searchInfo.value,
  924. pageNo: pagination.value.pageNo,
  925. pageSize: pagination.value.pageSize
  926. }
  927. params.idList = list?.map((m) => m.id) || []
  928. const data = await PipeTaskOrderApi.opinionReportedExcel(params)
  929. download.excel(data, `检验意见通知书-${dayJs().format('YYYYMMDDHHmmss')}.xlsx`)
  930. } catch (err) {
  931. console.log('err:log', err)
  932. ElMessage.error('导出失败')
  933. } finally {
  934. exportLoading.value = false
  935. loadDone()
  936. }
  937. }
  938. // 跟进记录
  939. const followRecordRespFlag = ref<boolean>(false)
  940. const recordLoading = ref<boolean>(false)
  941. const followRecordRespTableParams = reactive({
  942. pageNo: 1,
  943. pageSize: 10,
  944. total: 0
  945. })
  946. const followRecordRespList = ref<any[]>([])
  947. const currentRow = ref<Recordable>({})
  948. const followParams = ref<Recordable>({
  949. type: undefined,
  950. remark: undefined,
  951. distributionMethod: undefined,
  952. receiverPhone: undefined,
  953. receiver: undefined,
  954. receiveConfirmTime: undefined,
  955. followTime: new Date().getTime()
  956. })
  957. const followTypeList = reactive([
  958. {
  959. label: '消息推送',
  960. value: 0
  961. },
  962. {
  963. label: '跟进情况',
  964. value: 1
  965. },
  966. {
  967. label: '线下材料递交',
  968. value: 2
  969. },
  970. {
  971. label: '人工消息推送',
  972. value: 3
  973. },
  974. {
  975. label: '客户未回复意见书',
  976. value: 4
  977. }
  978. ])
  979. const getFollowTypeList = followTypeList.filter((item) => item.value !== 0)
  980. const getFollowRecordRespColumns = ref([
  981. {
  982. label: '序号',
  983. prop: 'index',
  984. fieldProps: {
  985. type: 'index',
  986. align: 'center',
  987. width: 80
  988. }
  989. },
  990. {
  991. label: '类型',
  992. prop: 'type',
  993. fieldProps: {
  994. align: 'center',
  995. minWidth: 120,
  996. showOverflowTooltip: true
  997. },
  998. render: (_row, value) => followTypeList.find((item) => item.value === value)?.label || ''
  999. },
  1000. {
  1001. label: '发送方式',
  1002. prop: 'distributionMethod',
  1003. fieldProps: {
  1004. align: 'center',
  1005. minWidth: 120,
  1006. showOverflowTooltip: true
  1007. }
  1008. },
  1009. {
  1010. label: '跟进记录手机号',
  1011. prop: 'followRecordReceiverPhone',
  1012. fieldProps: {
  1013. align: 'center',
  1014. minWidth: 140,
  1015. showOverflowTooltip: true
  1016. }
  1017. },
  1018. {
  1019. label: '跟进时间',
  1020. prop: 'followTime',
  1021. fieldProps: {
  1022. align: 'center',
  1023. minWidth: 135,
  1024. showOverflowTooltip: true
  1025. },
  1026. render: (_row, value) => dayJs(value).format('YYYY-MM-DD HH:mm:ss')
  1027. },
  1028. {
  1029. label: '备注',
  1030. prop: 'remark',
  1031. fieldProps: {
  1032. align: 'center',
  1033. minWidth: 255,
  1034. showOverflowTooltip: true
  1035. }
  1036. },
  1037. {
  1038. label: '跟进人',
  1039. prop: 'creatorName',
  1040. fieldProps: {
  1041. align: 'center',
  1042. minWidth: 120,
  1043. showOverflowTooltip: true
  1044. }
  1045. }
  1046. ])
  1047. const handleCloseFollowRecordRespDialog = () => {
  1048. followRecordRespFlag.value = false
  1049. currentRow.value = {}
  1050. }
  1051. const handleFollowTypeChange = (val: number) => {
  1052. followParams.value.distributionMethod = undefined
  1053. followParams.value.remark = val === 2 ? '客户线下递交整改材料' : ''
  1054. }
  1055. const handleFollowRecordRespConfirm = async () => {
  1056. if (!followParams.value.type) {
  1057. ElMessage.error('请选择跟进类型')
  1058. return
  1059. }
  1060. if (followParams.value.type === 3 && !followParams.value.distributionMethod) {
  1061. ElMessage.error('请输入发送方式')
  1062. return
  1063. }
  1064. if (followParams.value.type === 3 && !followParams.value.receiveConfirmTime) {
  1065. ElMessage.error('请选择确认接收时间')
  1066. return
  1067. }
  1068. if (!followParams.value.remark) {
  1069. ElMessage.error('请输入跟进记录')
  1070. return
  1071. }
  1072. if (!followParams.value.followTime) {
  1073. ElMessage.error('请输入跟进时间')
  1074. return
  1075. }
  1076. recordLoading.value = true
  1077. const params = {
  1078. ...followParams.value,
  1079. reportId: currentRow.value.reportId,
  1080. equipMainType: 300
  1081. }
  1082. if (followParams.value.type != 3) {
  1083. delete params.receiveConfirmTime
  1084. delete params.receiverPhone
  1085. delete params.receiver
  1086. }
  1087. try {
  1088. const res = await PipeTaskOrderApi.createFollowRecord(params)
  1089. followRecordRespFlag.value = false
  1090. currentRow.value = {}
  1091. if (res) {
  1092. ElMessage.success('保存成功')
  1093. followRecordRespFlag.value = false
  1094. getList()
  1095. }
  1096. } finally {
  1097. recordLoading.value = false
  1098. }
  1099. }
  1100. const handleFollowRecord = (row) => {
  1101. currentRow.value = row
  1102. followParams.value = {
  1103. type: undefined,
  1104. remark: undefined,
  1105. distributionMethod: undefined,
  1106. followTime: new Date().getTime()
  1107. }
  1108. followRecordRespTablePage()
  1109. followRecordRespFlag.value = true
  1110. }
  1111. const followRecordRespTablePage = async () => {
  1112. const params = {
  1113. pageNo: followRecordRespTableParams.pageNo,
  1114. pageSize: followRecordRespTableParams.pageSize,
  1115. reportId: currentRow.value.reportId
  1116. }
  1117. recordLoading.value = true
  1118. const recordRes = await PipeTaskOrderApi.getFollowRecordList(params)
  1119. followRecordRespList.value = recordRes?.list || []
  1120. followRecordRespTableParams.total = recordRes?.total || 0
  1121. recordLoading.value = false
  1122. }
  1123. const updateDialogVisible = ref(false)
  1124. const handleUpdateRow = (row) => {
  1125. updateFormData.value = {
  1126. id: row.reportId,
  1127. detailedInfo: row.detailedInfo
  1128. }
  1129. updateDialogVisible.value = true
  1130. }
  1131. const handleCloseUpdateDialog = () => {
  1132. updateDialogVisible.value = false
  1133. updateFormData.value = {}
  1134. }
  1135. const handleUpdateFollowRecordRespConfirm = async () => {
  1136. updateFormRef.value?.validate().then(() => {
  1137. recordLoading.value = true
  1138. PipeTaskOrderApi
  1139. .updateFollowRecord({ ...updateFormData.value })
  1140. .then(() => {
  1141. ElMessage.success('更新成功')
  1142. updateDialogVisible.value = false
  1143. getList()
  1144. })
  1145. .finally(() => {
  1146. recordLoading.value = false
  1147. })
  1148. })
  1149. }
  1150. const updateFormRef = ref<FormInstance>()
  1151. const updateFormData = ref<Recordable>({})
  1152. const updateFormRules = reactive({
  1153. detailedInfo: [{ required: true, message: '请输入详细信息', trigger: ['blur'] }]
  1154. })
  1155. // tableStatus 表格状态查询
  1156. const tableStatus = ref('')
  1157. const handleRadioChange = (val) => {
  1158. switch (val) {
  1159. case '1':
  1160. searchInfo.value.handlerId = userStore.getUser.id
  1161. searchInfo.value.mpSendStatus = ['4']
  1162. searchInfo.value.rectificationStatusList = ['0']
  1163. delete searchInfo.value.isOverdue
  1164. break
  1165. case '2':
  1166. searchInfo.value.handlerId = userStore.getUser.id
  1167. searchInfo.value.mpSendStatus = ['1', '2', '3']
  1168. searchInfo.value.rectificationStatusList = ['0']
  1169. delete searchInfo.value.isOverdue
  1170. break
  1171. case '3':
  1172. searchInfo.value.handlerId = userStore.getUser.id
  1173. searchInfo.value.rectificationStatusList = ['0']
  1174. searchInfo.value.isOverdue = true
  1175. break
  1176. default:
  1177. searchInfo.value = {
  1178. handlerId: userStore.getUser.id
  1179. }
  1180. break
  1181. }
  1182. getList()
  1183. }
  1184. // 下载意见书
  1185. const downloadFile = async (blob, filename) => {
  1186. try{
  1187. //创建一个链接来触发下载
  1188. const link = document.createElement('a')
  1189. const objectUrl = URL.createObjectURL(blob)
  1190. link.href = objectUrl
  1191. link.download = filename
  1192. // 触发点击事件来下载文件
  1193. document.body.appendChild(link)
  1194. link.click()
  1195. // 清理
  1196. document.body.removeChild(link)
  1197. URL.revokeObjectURL(objectUrl)
  1198. } catch (error) {console.error('下载文件时发生错误',error)
  1199. ElMessage.error('下载失败')
  1200. }
  1201. }
  1202. const handleRowDownload = async (row) => {
  1203. let data: any[] = []
  1204. data.push({
  1205. taskStatus: 100,
  1206. templateId: row.templateId,
  1207. reportUrl: '',
  1208. id: row.reportId,
  1209. })
  1210. const loadingInstance = ElLoading.service({
  1211. fullscreen: true,
  1212. text: '正在生成...'
  1213. })
  1214. const { reportedNo, opinionReportedUrl } = row
  1215. loadStart()
  1216. try {
  1217. // 调用 API 获取 ZIP blob
  1218. const pdfBlob = await PipeInputApi.handlePrint(data)
  1219. if (pdfBlob) {
  1220. downloadFile(pdfBlob, `${reportedNo}检验意见通知书.pdf`)
  1221. } else {
  1222. ElMessage.error('获取文件失败')
  1223. }
  1224. } catch (error) {
  1225. ElMessage.error('下载失败')
  1226. } finally {
  1227. loadingInstance.close()
  1228. loadDone()
  1229. }
  1230. }
  1231. const handleUnitCodeFn = (code) => {
  1232. if (!code) {
  1233. return ElMessage.warning('该单位信息异常!')
  1234. }
  1235. unitContainerFormRef.value?.open('', code)
  1236. }
  1237. const handlePreviewClose = () => {
  1238. currentPreviewId.value = ''
  1239. currentFilename.value = ''
  1240. currentReportId.value = ''
  1241. previewVisible.value = false
  1242. }
  1243. const { bpmUserId } = route.query as Recordable
  1244. if (bpmUserId) {
  1245. searchInfo.value.inspectorIds = [bpmUserId]
  1246. searchInfo.value.rectificationStatus = '0'
  1247. }
  1248. getList()
  1249. getDeptDataList()
  1250. </script>
  1251. <style lang="scss" scoped>
  1252. .report-name-list {
  1253. word-wrap: break-word; /* 自动换行 */
  1254. white-space: pre-wrap; /* 保留空格并换行 */
  1255. word-break: break-word; /* 在单词之间也能换行 */
  1256. }
  1257. .toolBox {
  1258. margin-bottom: 20px;
  1259. }
  1260. .reportDOList-item {
  1261. overflow: hidden;
  1262. text-overflow: ellipsis;
  1263. white-space: nowrap;
  1264. width: 100%;
  1265. //max-width: 150px;
  1266. }
  1267. .report-item-animated {
  1268. line-height: 1.5;
  1269. }
  1270. .report-name-list {
  1271. position: relative;
  1272. .collapsed::after {
  1273. content: '';
  1274. position: absolute;
  1275. bottom: 0;
  1276. left: 0;
  1277. right: 0;
  1278. height: 15px;
  1279. background: linear-gradient(transparent, rgba(255, 255, 255, 0.9));
  1280. pointer-events: none;
  1281. }
  1282. }
  1283. .dialog-footer {
  1284. box-sizing: border-box;
  1285. padding-top: 20px;
  1286. margin-top: 20px;
  1287. display: flex;
  1288. justify-content: flex-end;
  1289. align-items: center;
  1290. border-top: 1px solid #dcdfe6;
  1291. }
  1292. </style>