index.vue 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821
  1. <template>
  2. <ContentWrap>
  3. <!-- 搜索工作栏 -->
  4. <el-form
  5. class="-mb-15px"
  6. :model="taskStatusQueryParams[taskStatus]"
  7. ref="queryFormRef"
  8. :inline="true"
  9. label-width="100px"
  10. >
  11. <el-row :gutter="20" class="flex-wrap" style="margin-right: 0">
  12. <template v-for="(item, index) in formItems" :key="item.prop">
  13. <el-col :xs="24" :sm="12" :md="8" :lg="6">
  14. <el-collapse-transition>
  15. <div v-show="isSearchExpanded || index < 4">
  16. <el-form-item :label="item.label" :prop="item.prop" class="w-full">
  17. <template v-if="item.component === 'select-modal'">
  18. <el-select
  19. v-model="taskStatusQueryParams[taskStatus][item.prop]"
  20. readonly
  21. clearable
  22. placeholder="请选择"
  23. multiple
  24. popper-class="user-select-popper"
  25. @click.stop.prevent="() => handleOpenUserDialog(item.selctOptions, item.prop)"
  26. class="w-full"
  27. >
  28. <el-option
  29. v-for="child in item.selctOptions"
  30. :key="child && child.id"
  31. :label="child.nickName"
  32. :value="child.id"
  33. />
  34. </el-select>
  35. </template>
  36. <component
  37. v-else
  38. :is="item.component"
  39. v-model="taskStatusQueryParams[taskStatus][item.prop]"
  40. v-bind="item.attrs"
  41. @keyup.enter="handleQuery"
  42. class="w-full min-w-[180px] sm:min-w-[220px] lg:min-w-[240px]"
  43. >
  44. <!-- select 的 option 渲染 -->
  45. <template v-if="item.component === 'el-select'">
  46. <el-option
  47. v-for="child in item.children"
  48. :key="child.value"
  49. :label="child.label"
  50. :value="child.value"
  51. />
  52. </template>
  53. </component>
  54. </el-form-item>
  55. </div>
  56. </el-collapse-transition>
  57. </el-col>
  58. </template>
  59. </el-row>
  60. <!-- 按钮区 -->
  61. <el-row class="flex justify-end mt-2">
  62. <el-form-item>
  63. <el-button @click="handleQuery">
  64. <Icon icon="ep:search" class="mr-5px" /> 搜索
  65. </el-button>
  66. <el-button @click="resetQuery">
  67. <Icon icon="ep:refresh" class="mr-5px" /> 重置
  68. </el-button>
  69. <!-- <el-button type="primary" @click="showSettingDialog">-->
  70. <!-- <Icon icon="ep:user" class="mr-5px" /> 审核配置-->
  71. <!-- </el-button>-->
  72. <el-button link @click="isSearchExpanded = !isSearchExpanded">
  73. <el-icon>
  74. <ArrowUp v-if="isSearchExpanded" />
  75. <ArrowDown v-else />
  76. </el-icon>
  77. {{ isSearchExpanded ? '收起' : '展开' }}
  78. </el-button>
  79. </el-form-item>
  80. </el-row>
  81. </el-form>
  82. </ContentWrap>
  83. <!-- 列表 -->
  84. <ContentWrap>
  85. <!-- <el-radio-group v-model="taskStatus" class="mb-10px" @change="handleQuery">-->
  86. <!-- <el-radio-button label="报告审批" value="reportApprove" />-->
  87. <!-- </el-radio-group>-->
  88. <el-table
  89. v-loading="loading"
  90. :data="list"
  91. class="cursor-pointer"
  92. border
  93. :stripe="true"
  94. ref="MyTaskTableListRef"
  95. @row-dblclick="handleRowDblclick"
  96. >
  97. <el-table-column type="selection" align="center" width="55" />
  98. <el-table-column label="任务单号" align="center" prop="orderNo" min-width="150px" />
  99. <el-table-column label="工程号" align="center" prop="projectNo" min-width="200px">
  100. <template #default="{ row }">
  101. <div class="project-info"
  102. v-for="(item, index) in row.projectNoList"
  103. :key="item?.id || index">
  104. <el-tag type="success" class="project-name-tag">{{ item }}</el-tag>
  105. </div>
  106. </template>
  107. <!-- <template #default="{ row }">-->
  108. <!-- <div class="project-info">-->
  109. <!-- <div class="project-no">{{ row.projectNo }}</div>-->
  110. <!-- <div v-if="row.projectName" class="project-name-wrapper mt-4px">-->
  111. <!-- <el-tooltip-->
  112. <!-- v-if="row.projectName.length > 15"-->
  113. <!-- :content="row.projectName"-->
  114. <!-- placement="top"-->
  115. <!-- >-->
  116. <!-- <el-tag type="success" class="project-name-tag">-->
  117. <!-- <span class="project-name-text">{{ row.projectName }}</span>-->
  118. <!-- </el-tag>-->
  119. <!-- </el-tooltip>-->
  120. <!-- <el-tag v-else type="success" class="project-name-tag">-->
  121. <!-- <span class="project-name-text">{{ row.projectName }}</span>-->
  122. <!-- </el-tag>-->
  123. <!-- </div>-->
  124. <!-- </div>-->
  125. <!-- </template>-->
  126. </el-table-column>
  127. <!-- <el-table-column label="设备名称" align="center" prop="equipName" min-width="120px" /> -->
  128. <el-table-column label="使用单位" align="center" prop="unitName" min-width="150px" />
  129. <el-table-column label="检验性质" align="center" prop="checkType" min-width="120px">
  130. <template #default="scope">
  131. {{ PressurePipeCheckTypeMap[scope.row.checkType] }}
  132. </template>
  133. </el-table-column>
  134. <!-- 检验项目 -->
  135. <el-table-column label="检验项目" prop="reportDOList" min-width="200px">
  136. <template #default="scope">
  137. <div v-if="scope.row.reportDOList && scope.row.reportDOList.length > 0">
  138. <div class="reportDOList-item">
  139. <!-- 数据大于2条时,使用展开收起功能 -->
  140. <div v-if="scope.row.reportDOList.length > 2">
  141. <!-- 始终显示的前2条数据 -->
  142. <div
  143. v-for="(item, index) in scope.row.reportDOList.slice(0, 2)"
  144. :key="item?.id || index"
  145. class="report-item"
  146. >
  147. <div style="color: #015293">
  148. {{ index + 1 }}、{{ item?.reportName }}
  149. </div>
  150. <div v-if="item?.fee" style="color: #015293">
  151. (费用:{{ item?.fee }})
  152. </div>
  153. </div>
  154. <!-- 可展开的剩余数据 -->
  155. <div
  156. class="expandable-content"
  157. :style="{
  158. maxHeight: isExpanded(scope.row)
  159. ? `${(scope.row.reportDOList.length - 2) * 40}px`
  160. : '0px',
  161. transition: 'max-height 0.4s cubic-bezier(0.4, 0, 0.2, 1)',
  162. overflow: 'hidden'
  163. }"
  164. >
  165. <div
  166. v-for="(item, index) in scope.row.reportDOList.slice(2)"
  167. :key="item?.id || `extra-${index}`"
  168. class="report-item-animated"
  169. :style="{
  170. opacity: isExpanded(scope.row) ? 1 : 0,
  171. transform: isExpanded(scope.row) ? 'translateY(0)' : 'translateY(-10px)',
  172. transition: `all 0.3s ease ${index * 50}ms`,
  173. padding: '2px 0'
  174. }"
  175. >
  176. <div link type="primary" style="color: #015293">
  177. {{ index + 3 }}、{{ item?.reportName }}
  178. </div>
  179. <div v-if="item?.fee" style="color: #015293">
  180. (费用:{{ item?.fee }})
  181. </div>
  182. </div>
  183. </div>
  184. <!-- 展开收起按钮 -->
  185. <div class="expand-control" style="text-align: center; margin-top: 8px">
  186. <el-button
  187. size="small"
  188. link
  189. type="primary"
  190. @click="toggleExpand(scope.row)"
  191. class="expand-button"
  192. :style="{
  193. transition: 'all 0.2s ease'
  194. }"
  195. >
  196. <span style="margin-right: 4px">
  197. {{
  198. isExpanded(scope.row)
  199. ? '收起'
  200. : `查看更多(${scope.row.reportDOList.length - 2}条)`
  201. }}
  202. </span>
  203. <el-icon
  204. :style="{
  205. width: '12px',
  206. height: '12px',
  207. display: 'inline-block',
  208. transition: 'transform 0.3s cubic-bezier(0.4, 0, 0.2, 1)',
  209. transform: isExpanded(scope.row) ? 'rotate(180deg)' : 'rotate(0deg)'
  210. }"
  211. >
  212. <ArrowDown />
  213. </el-icon>
  214. </el-button>
  215. </div>
  216. </div>
  217. <!-- 数据小于等于2条时,直接显示所有数据 -->
  218. <div v-else>
  219. <div
  220. v-for="(item, index) in scope.row.reportDOList"
  221. :key="item?.id || index"
  222. class="report-item"
  223. >
  224. <div style="color: #015293">
  225. {{ index + 1 }}、{{ item?.reportName }}
  226. </div>
  227. <div v-if="item?.fee" style="color: #015293">
  228. (费用:{{ item?.fee }})
  229. </div>
  230. </div>
  231. </div>
  232. </div>
  233. </div>
  234. <div v-else class="empty-data">-</div>
  235. </template>
  236. </el-table-column>
  237. <el-table-column label="主报告状态" align="center" prop="taskStatus" min-width="150px">
  238. <template #default="scope">
  239. <el-tag :type="getTypeColor(scope.row.taskStatus)">{{
  240. PressureCheckerMyTaskStatusMap[scope.row.taskStatus]
  241. }}</el-tag>
  242. </template>
  243. </el-table-column>
  244. <el-table-column
  245. label="剩余期限 (工作日)"
  246. align="center"
  247. prop="remainingDays"
  248. min-width="140px"
  249. />
  250. <el-table-column label="检验时间" align="center" prop="checkDate" min-width="120px">
  251. <template #default="scope">
  252. {{ formatArrayDate(scope.row.checkDate) }}
  253. </template>
  254. </el-table-column>
  255. <el-table-column label="项目负责人" align="center" prop="manager" min-width="120px">
  256. <template #default="scope">
  257. {{
  258. scope.row.manager
  259. ? scope.row.manager.nickname + ' (' + scope.row.manager.employeeNo + ')'
  260. : '-'
  261. }}
  262. </template>
  263. </el-table-column>
  264. <!-- 主检人 -->
  265. <el-table-column label="主检人" align="center" prop="mainInspector" min-width="120px">
  266. <template #default="scope">
  267. {{
  268. scope.row.mainCheckerUser
  269. ? scope.row.mainCheckerUser.nickname +
  270. ' (' +
  271. scope.row.mainCheckerUser.employeeNo +
  272. ')'
  273. : '-'
  274. }}
  275. </template>
  276. </el-table-column>
  277. <el-table-column label="检验员" align="center" prop="checkUsers" min-width="150px">
  278. <template #default="scope">
  279. <div v-if="scope.row.checkUsers && scope.row.checkUsers.length > 0">
  280. <div v-for="user in scope.row.checkUsers" :key="user.id">
  281. {{ user.nickname }} ({{ user.employeeNo }})
  282. </div>
  283. </div>
  284. <div v-else>-</div>
  285. </template>
  286. </el-table-column>
  287. <el-table-column label="操作" align="center" min-width="150px" fixed="right">
  288. <template #default="scope">
  289. <div class="flex flex-col gap-1">
  290. <el-button link type="primary" @click="handleEdit(scope.row.id)"> 审批 </el-button>
  291. </div>
  292. </template>
  293. </el-table-column>
  294. </el-table>
  295. <!-- 分页 -->
  296. <Pagination
  297. :total="total"
  298. v-model:page="taskStatusQueryParams[taskStatus].pageNo"
  299. v-model:limit="taskStatusQueryParams[taskStatus].pageSize"
  300. @pagination="getList"
  301. />
  302. </ContentWrap>
  303. <SettingDialog ref="formRef" />
  304. <!-- 选择人员公共弹窗 -->
  305. <CustomDialog
  306. v-model="customUserDialogVisible"
  307. :dialogAttrs="{
  308. zIndex: 10006
  309. }"
  310. @confirm="handleUserConfirm"
  311. >
  312. <el-input
  313. v-model="userQueryData.nickName"
  314. clearable
  315. placeholder="请输入名称"
  316. @keyup.enter="handleFetchUserList"
  317. style="margin-bottom: 14px"
  318. >
  319. <template #append>
  320. <el-button @click="handleFetchUserList">
  321. <Icon icon="ep:search" />
  322. </el-button>
  323. </template>
  324. </el-input>
  325. <SmartTable
  326. ref="userTableRef"
  327. v-model:pageNo="userQueryData.pageNo"
  328. v-model:pagesize="userQueryData.pageSize"
  329. :total="userQueryData.total"
  330. v-model:columns="userColumns"
  331. :data="userTableList"
  332. :buttons="[]"
  333. :showSettingTools="false"
  334. :showSearch="false"
  335. :showRefresh="false"
  336. @on-page-size-change="onPageSizeChange"
  337. @on-page-no-change="onPageNoChange"
  338. />
  339. </CustomDialog>
  340. </template>
  341. <script setup lang="ts">
  342. import { ref, reactive, onMounted, computed } from 'vue'
  343. import { formatArrayDate } from '@/utils/formatTime'
  344. import { ArrowDown, ArrowUp } from '@element-plus/icons-vue'
  345. import { PipeTaskOrderApi, PipeTaskOrderOrderItemVO } from '@/api/pressure2/pipetaskorder'
  346. import {
  347. PressurePipeCheckTypeMap,
  348. PressureCheckerMyTaskStatusMap,
  349. PressureCheckerMyTaskStatus,
  350. PressureTaskOrderTaskStatus
  351. } from '@/utils/constants'
  352. import { ElMessageBox, ElMessage } from 'element-plus'
  353. import { useRouter, useRoute } from 'vue-router'
  354. import SettingDialog from '@/views/pressure/checker/components/SettingDialog.vue'
  355. const router = useRouter()
  356. import SmartTable from '@/components/SmartTable/SmartTable'
  357. import { getUserList } from '@/api/common/user'
  358. import { useUserStore } from '@/store/modules/user'
  359. import { cloneDeep } from 'lodash-es'
  360. import { useEmitt } from '@/hooks/web/useEmitt'
  361. const userStore = useUserStore()
  362. const userInfo = computed(() => userStore.user)
  363. const route = useRoute()
  364. const getTypeColor = (status: string | number) => {
  365. const statusMap = {
  366. [PressureTaskOrderTaskStatus.WAIT_CONFIRM]: 'primary',
  367. [PressureTaskOrderTaskStatus.CANCELLED]: 'info',
  368. [PressureTaskOrderTaskStatus.AUDITING_EDIT]: 'warning',
  369. [PressureTaskOrderTaskStatus.AUDITING_CANCEL]: 'warning',
  370. [PressureTaskOrderTaskStatus.AUDITING_TIME]: 'warning',
  371. [PressureTaskOrderTaskStatus.CONFIRMED]: 'success',
  372. [PressureTaskOrderTaskStatus.RECORD_INPUT]: 'warning',
  373. [PressureTaskOrderTaskStatus.RECORD_CHECK]: 'warning',
  374. [PressureTaskOrderTaskStatus.REPORT_INPUT]: 'warning',
  375. [PressureTaskOrderTaskStatus.REPORT_AUDIT]: 'warning',
  376. [PressureTaskOrderTaskStatus.REPORT_APPROVE]: 'warning',
  377. [PressureTaskOrderTaskStatus.REPORT_CONFIRMATION]: 'warning',
  378. [PressureTaskOrderTaskStatus.REPORT_END]: 'success'
  379. }
  380. return statusMap[status] || 'info'
  381. }
  382. /** 报告编制 列表 */
  383. defineOptions({ name: 'ReportRatifyBoiler' })
  384. const isSearchExpanded = ref<boolean>(false)
  385. const loading = ref(true)
  386. const list = ref<PipeTaskOrderOrderItemVO[]>([])
  387. const total = ref(0)
  388. const queryParams = reactive<Recordable>({
  389. pageNo: 1,
  390. pageSize: 10,
  391. orderNo: undefined,
  392. unitName: undefined,
  393. checkType: undefined,
  394. projectNo: undefined,
  395. productNo: undefined,
  396. checkDate: [],
  397. // checkUserStrIds: [userInfo.value.id],
  398. // managerStrIds: [userInfo.value.id],
  399. checkUserStrIds: [],
  400. managerStrIds: [],
  401. // taskStatusList: ['520'],
  402. remainingDays: undefined,
  403. mainCheckerStrIds: [userInfo.value.id]
  404. })
  405. const defaultFormValue = {
  406. pageNo: 1,
  407. pageSize: 10,
  408. orderNo: undefined,
  409. unitName: undefined,
  410. checkType: undefined,
  411. projectNo: undefined,
  412. productNo: undefined,
  413. checkDate: [],
  414. // checkUserStrIds: [userInfo.value.id],
  415. // managerStrIds: [userInfo.value.id],
  416. checkUserStrIds: [],
  417. managerStrIds: [],
  418. // taskStatusList: ['520'],
  419. remainingDays: undefined,
  420. mainCheckerStrIds: [userInfo.value.id]
  421. }
  422. const taskStatus = ref('reportApprove')
  423. const taskStatusQueryParams =reactive({
  424. reportApprove: {...defaultFormValue, taskStatus: 700},
  425. })
  426. const ReportPreparationStatusOpts = {
  427. [PressureCheckerMyTaskStatus.REPORT_APPROVE]: '报告审批'
  428. }
  429. const formItems = [
  430. {
  431. label: '工程号',
  432. prop: 'projectNo',
  433. component: 'el-input',
  434. attrs: {
  435. placeholder: '请输入工程号',
  436. clearable: true
  437. }
  438. },
  439. // {
  440. // label: '任务状态',
  441. // prop: 'taskStatusList',
  442. // component: 'el-select',
  443. // attrs: {
  444. // placeholder: '请选择任务状态',
  445. // clearable: true,
  446. // multiple: true
  447. // },
  448. // children: [
  449. // // { label: '全部', value: 'all' },
  450. // ...Object.entries(ReportPreparationStatusOpts).map(([key, label]) => ({
  451. // label,
  452. // value: key
  453. // }))
  454. // ]
  455. // },
  456. {
  457. label: '任务单号',
  458. prop: 'orderNo',
  459. component: 'el-input',
  460. attrs: {
  461. placeholder: '请输入任务单号',
  462. clearable: true
  463. }
  464. },
  465. {
  466. label: '使用单位',
  467. prop: 'unitName',
  468. component: 'el-input',
  469. attrs: {
  470. placeholder: '请输入使用单位',
  471. clearable: true
  472. }
  473. },
  474. {
  475. label: '检验性质',
  476. prop: 'checkType',
  477. component: 'el-select',
  478. attrs: {
  479. placeholder: '请选择检验性质',
  480. clearable: true
  481. },
  482. children: Object.entries(PressurePipeCheckTypeMap).map(([key, label]) => ({
  483. label,
  484. value: key
  485. }))
  486. },
  487. {
  488. label: '检验时间',
  489. prop: 'checkDate',
  490. component: 'el-date-picker',
  491. attrs: {
  492. type: 'daterange',
  493. placeholder: '请选择时间',
  494. startPlaceholder: '开始日期',
  495. endPlaceholder: '结束日期',
  496. valueFormat: 'YYYY-MM-DD HH:mm:ss',
  497. defaultTime: [new Date('1 00:00:00'), new Date('1 23:59:59')],
  498. class: '!w-240px'
  499. }
  500. },
  501. {
  502. label: '主检人',
  503. prop: 'mainCheckerStrIds',
  504. component: 'select-modal',
  505. selctOptions: [{ id: userInfo.value.id, nickName: userInfo.value?.nickname }],
  506. attrs: {
  507. placeholder: '请输入主检人名称',
  508. clearable: true
  509. }
  510. },
  511. {
  512. label: '检验员',
  513. prop: 'checkUserStrIds',
  514. component: 'select-modal',
  515. selctOptions: [{ id: userInfo.value.id, nickName: userInfo.value?.nickname }],
  516. attrs: {
  517. placeholder: '请输入检验员名称',
  518. clearable: true
  519. }
  520. },
  521. {
  522. label: '项目负责人',
  523. prop: 'managerStrIds',
  524. component: 'select-modal',
  525. selctOptions: [{ id: userInfo.value.id, nickName: userInfo.value?.nickname }],
  526. attrs: {
  527. placeholder: '请输入项目负责人',
  528. clearable: true
  529. }
  530. },
  531. // {
  532. // label: '剩余期限',
  533. // prop: 'remainingDays',
  534. // component: 'el-input',
  535. // attrs: {
  536. // placeholder: '请输入剩余期限',
  537. // clearable: true
  538. // }
  539. // },
  540. // {
  541. // label: '出厂编号',
  542. // prop: 'productNo',
  543. // component: 'el-input',
  544. // attrs: {
  545. // placeholder: '请输入出厂编号',
  546. // clearable: true
  547. // }
  548. // }
  549. ]
  550. const queryFormRef = ref()
  551. const formRef = ref()
  552. const showSettingDialog = () => {
  553. formRef.value.open()
  554. }
  555. // 存储展开状态的响应式数据
  556. const expandedRows = ref(new Set())
  557. // 判断行是否展开
  558. const isExpanded = (row) => {
  559. return expandedRows.value.has(row.id || JSON.stringify(row))
  560. }
  561. // 切换展开状态
  562. const toggleExpand = (row) => {
  563. const rowKey = row.id || JSON.stringify(row)
  564. if (expandedRows.value.has(rowKey)) {
  565. expandedRows.value.delete(rowKey)
  566. } else {
  567. expandedRows.value.add(rowKey)
  568. }
  569. }
  570. const formattingFn = (reportDOList: Record<string, any>[]) => {
  571. return `<ol style="padding: 10px">${reportDOList
  572. .map((item) => `<li>${item.reportName}</li>`)
  573. .join('')}</ol>`
  574. }
  575. const MyTaskTableListRef = ref() // table的实例
  576. // 出具报告对话框状态
  577. const generateReportDialogVisible = ref(false)
  578. const currentReportItem = ref<any>(null)
  579. /** 查询列表 */
  580. const getList = async () => {
  581. loading.value = true
  582. try {
  583. const params: any = cloneDeep(taskStatusQueryParams[unref(taskStatus)])
  584. if (params.taskStatus === 'all') {
  585. params.taskStatus = undefined
  586. }
  587. params.checkUserStrIds = params.checkUserStrIds.join(',')
  588. params.managerStrIds = params.managerStrIds.join(',')
  589. params.mainCheckerStrIds = params.mainCheckerStrIds.join(',')
  590. // params.taskStatusList = params.taskStatusList.join(',')
  591. if(!params.checkUserStrIds) delete params.checkUserStrIds
  592. if(!params.managerStrIds) delete params.managerStrIds
  593. if(!params.mainCheckerStrIds) delete params.mainCheckerStrIds
  594. if(!params.taskStatusList) delete params.taskStatusList
  595. const data = await PipeTaskOrderApi.prepareReportPage(params)
  596. list.value = data.list
  597. total.value = data.total
  598. } catch (error) {
  599. console.error('获取我的任务列表失败:', error)
  600. ElMessage.error('获取报告编制列表失败')
  601. list.value = []
  602. total.value = 0
  603. } finally {
  604. loading.value = false
  605. }
  606. }
  607. /** 搜索按钮操作 */
  608. const handleQuery = () => {
  609. taskStatusQueryParams[unref(taskStatus)].pageNo = 1
  610. getList()
  611. }
  612. /** 重置按钮操作 */
  613. const resetQuery = () => {
  614. queryFormRef.value.resetFields()
  615. // queryParams.taskStatusList = ['520']
  616. handleQuery()
  617. }
  618. // 修改后的编辑/查看详情操作
  619. const handleEdit = (id: string) => {
  620. router.push({ name: 'PipeCheckerTaskDetail', query: { id, type: 'reportRatify' } })
  621. }
  622. const handleRowDblclick = (row: Record<string, any>) => {
  623. if (row.isClaim === false) {
  624. return
  625. }
  626. router.push({ name: 'PipeCheckerTaskDetail', query: { id: row.id, type: 'reportRatify' } })
  627. }
  628. //------------人员选择弹窗------------------------
  629. const checkFormOptions = ref<any[]>([])
  630. const fieldKey = ref('')
  631. const userTableRef = ref()
  632. const customUserDialogVisible = ref(false)
  633. interface UserListQuery {
  634. nickName: string
  635. pageNo: number
  636. pageSize: number
  637. total?: number
  638. }
  639. const userQueryData = reactive<UserListQuery>({
  640. nickName: '',
  641. pageNo: 1,
  642. pageSize: 10,
  643. total: 0
  644. })
  645. const userTableList = ref<any[]>([])
  646. const userColumns = ref<any[]>([
  647. {
  648. type: 'selection',
  649. width: '50px'
  650. },
  651. {
  652. label: '工号',
  653. prop: 'employeeNo'
  654. },
  655. {
  656. label: '姓名',
  657. prop: 'nickname'
  658. },
  659. {
  660. label: '部门',
  661. prop: 'deptName'
  662. }
  663. ])
  664. // 打开用户选择框
  665. const handleOpenUserDialog = (options: any, key: string) => {
  666. checkFormOptions.value = options
  667. fieldKey.value = key
  668. userQueryData.nickName = ''
  669. userQueryData.pageNo = 1
  670. userQueryData.pageSize = 10
  671. handleFetchUserList()
  672. }
  673. // 获取用户信息
  674. const handleFetchUserList = async () => {
  675. const queryParams: UserListQuery = {
  676. ...userQueryData
  677. }
  678. delete queryParams.total
  679. const result = await getUserList(queryParams)
  680. userTableList.value = result.list
  681. userQueryData.total = result.total
  682. customUserDialogVisible.value = true
  683. }
  684. const onPageSizeChange = (val) => {
  685. userQueryData.pageSize = val
  686. handleFetchUserList()
  687. }
  688. const onPageNoChange = (val) => {
  689. userQueryData.pageNo = val
  690. handleFetchUserList()
  691. }
  692. const handleUserConfirm = () => {
  693. console.log('getTableRef', userTableRef.value.getTableRef())
  694. const selectRows = userTableRef.value.getTableRef().getSelectionRows()
  695. console.log('selectRows', selectRows)
  696. // 过滤组合合成options
  697. const currOptions = checkFormOptions.value.map((item) => item.id) || []
  698. selectRows
  699. .filter((item) => !currOptions.includes(item.id))
  700. .forEach((item) => {
  701. checkFormOptions.value.push({
  702. id: item.id,
  703. nickName: item.nickname,
  704. employeeNo: item.employeeNo
  705. })
  706. })
  707. taskStatusQueryParams[unref(taskStatus)][unref(fieldKey)] = [
  708. ...new Set([...taskStatusQueryParams[unref(taskStatus)][unref(fieldKey)], ...selectRows.map((row) => row.id)])
  709. ]
  710. // queryParams[fieldKey.value] = [
  711. // ...new Set([...queryParams[fieldKey.value], ...selectRows.map((row) => row.id)])
  712. // ]
  713. customUserDialogVisible.value = false
  714. }
  715. //------------------------------------
  716. const { emitter } = useEmitt()
  717. const { bpmUserId } = route.query as Recordable
  718. if (bpmUserId) {
  719. taskStatus.value = 'reportInput'
  720. taskStatusQueryParams[unref(taskStatus)].mainCheckerStrIds = [bpmUserId]
  721. taskStatusQueryParams[unref(taskStatus)].taskStatus = '520'
  722. }
  723. /** 初始化 **/
  724. onMounted(() => {
  725. getList()
  726. emitter.on('refresh-report-reportRatify-pipe', ()=> {
  727. getList();
  728. })
  729. })
  730. onUnmounted(() => {
  731. emitter.off('refresh-report-reportRatify-pipe')
  732. })
  733. </script>
  734. <style lang="scss" scoped>
  735. .cursor-pointer .el-table__row {
  736. cursor: pointer;
  737. }
  738. .report-item {
  739. display: flex;
  740. flex-direction: column;
  741. }
  742. .report-item-animated {
  743. line-height: 1.5;
  744. }
  745. .report-name-list {
  746. position: relative;
  747. .collapsed::after {
  748. content: '';
  749. position: absolute;
  750. bottom: 0;
  751. left: 0;
  752. right: 0;
  753. height: 15px;
  754. background: linear-gradient(transparent, rgba(255, 255, 255, 0.9));
  755. pointer-events: none;
  756. }
  757. }
  758. .project-info {
  759. display: flex;
  760. flex-direction: column;
  761. align-items: center;
  762. }
  763. .project-no {
  764. width: 100%;
  765. text-align: center;
  766. margin-bottom: 2px;
  767. }
  768. .project-name-tag {
  769. max-width: 100%;
  770. display: inline-flex;
  771. .project-name-text {
  772. display: inline-block;
  773. overflow: hidden;
  774. text-overflow: ellipsis;
  775. white-space: nowrap;
  776. max-width: 180px;
  777. }
  778. }
  779. </style>
  780. <style>
  781. .user-select-popper {
  782. display: none !important;
  783. }
  784. </style>