first-itemcopy.vue 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943
  1. <template>
  2. <div id="first-item-node-layout-target" class="hc-layout-box">
  3. <div v-show="!isFirstReportDrawer" :style="`width:${leftWidth}px;`" class="hc-layout-left-box bg-white">
  4. <div class="hc-project-box">
  5. <div class="hc-project-icon-box">
  6. <HcIcon name="stack" />
  7. </div>
  8. <div class="ml-2 project-name-box">
  9. <span class="project-alias">{{ projectInfo.name }}</span>
  10. </div>
  11. </div>
  12. <div class="hc-tree-box">
  13. <el-scrollbar>
  14. <WbsTree
  15. :auto-expand-keys="TreeAutoExpandKeys" :contract-id="contractId" :project-id="projectId"
  16. @node-tap="nodeWbsElTreeClick"
  17. />
  18. </el-scrollbar>
  19. </div>
  20. <!-- 左右拖动 -->
  21. <div class="horizontal-drag-line" @mousedown="onmousedown" />
  22. </div>
  23. <div v-show="!isFirstReportDrawer" class="hc-layout-content-box first-item">
  24. <HcNewCard :scrollbar="false" action-size="lg">
  25. <template #header>
  26. <HcTooltip v-if="tabTypeKey === 'mark'" keys="other-first-item-report">
  27. <el-button
  28. :disabled="tableSelectionKeys.length <= 0" hc-btn type="primary"
  29. @click="firstReportClick"
  30. >
  31. <HcIcon name="send-plane-2" />
  32. <span>上报首件</span>
  33. </el-button>
  34. </HcTooltip>
  35. <HcTooltip v-if="tabTypeKey === 'query'" keys="other-first-item-report-approval">
  36. <el-button
  37. :disabled="tableSelectionKeys.length <= 0" hc-btn type="primary"
  38. @click="reportModalClick(1)"
  39. >
  40. <HcIcon name="send-plane-2" />
  41. <span>上报审批</span>
  42. </el-button>
  43. </HcTooltip>
  44. <HcTooltip v-if="tabTypeKey === 'query'" keys="other-first-item-repeal">
  45. <el-button :disabled="tableSelectionKeys.length <= 0" hc-btn @click="batchAbolishClick">
  46. <HcIcon name="delete-bin-3" />
  47. <span>批量废除</span>
  48. </el-button>
  49. </HcTooltip>
  50. <HcTooltip keys="other-first-item-down-print">
  51. <el-button
  52. :disabled="tableSelectionKeys.length <= 0" :loading="printLoading" hc-btn
  53. @click="batchPrint"
  54. >
  55. <HcIcon name="printer" />
  56. <span>预览/打印</span>
  57. </el-button>
  58. </HcTooltip>
  59. </template>
  60. <template #extra>
  61. <HcNewSwitch :datas="tabTypeTab" :keys="tabTypeKey" size="default" @change="tabTypeChange" />
  62. </template>
  63. <template #search>
  64. <div class="w-32">
  65. <el-select v-model="searchForm.status" clearable placeholder="流程状态">
  66. <el-option
  67. v-for="item in processStatus" :label="item.dictValue"
  68. :value="item.dictKey"
  69. />
  70. </el-select>
  71. </div>
  72. <div class="w-32 ml-3">
  73. <el-select v-model="searchForm.reportNumber" clearable placeholder="上报批次">
  74. <el-option v-for="item in reportBatch" :label="item" :value="item" />
  75. </el-select>
  76. </div>
  77. <div class="w-64 ml-3">
  78. <HcDatePicker :dates="betweenTime" clearable @change="betweenTimeUpdate" />
  79. </div>
  80. <div class="w-64 ml-3">
  81. <el-input
  82. v-model="searchForm.queryValue" clearable placeholder="请输入名称关键词检索"
  83. @keyup="keyUpEvent"
  84. />
  85. </div>
  86. <div class="ml-2">
  87. <el-button type="primary" @click="searchClick">
  88. <HcIcon name="search-2" />
  89. <span>搜索</span>
  90. </el-button>
  91. </div>
  92. </template>
  93. <HcTable
  94. ref="tableListRef" :column="tableListColumn" :datas="tableListData" :loading="tableLoading"
  95. is-new :index-style="{ width: 60 }" is-check :check-style="{ width: 29 }"
  96. @selection-change="tableSelectionChange"
  97. >
  98. <template #name="{ row }">
  99. <span class="text-link" @click="tableRowName(row)">{{ row?.name }}</span>
  100. </template>
  101. <template #waitingUserList="{ row }">
  102. <template v-for="item in row.waitingUserList">
  103. <el-tag
  104. v-if="item.waitingUserName"
  105. :type="`${item.status === 2 ? 'success' : item.status === 3 ? 'warning' : item.status === 999 ? 'danger' : 'info'}`"
  106. class="mx-1" effect="dark"
  107. >
  108. {{ item.waitingUserName }}
  109. </el-tag>
  110. </template>
  111. </template>
  112. <template #taskStatusStr="{ row }">
  113. <el-tag
  114. v-if="row.taskStatusStr"
  115. :type="`${row.status === 2 ? 'success' : row.status === 0 ? 'warning' : row.status === 1 ? 'danger' : 'info'}`"
  116. class="mx-1" effect="dark"
  117. >
  118. {{ row.taskStatusStr }}
  119. </el-tag>
  120. </template>
  121. </HcTable>
  122. <template #action>
  123. <div class="lr-dialog-footer">
  124. <div class="left">
  125. <span class="text-success">任务人中:</span>
  126. <el-tag class="mx-1" effect="dark" type="success">已签字</el-tag>
  127. <el-tag class="mx-1" effect="dark" type="warning">已废除</el-tag>
  128. <el-tag class="mx-1" effect="dark" type="danger">签字异常</el-tag>
  129. </div>
  130. <div class="right">
  131. <HcPages :pages="searchForm" @change="pageChange" />
  132. </div>
  133. </div>
  134. </template>
  135. </HcNewCard>
  136. </div>
  137. <!-- 上报首件 -->
  138. <HcDrawer
  139. :is-card="false" :show="isFirstReportDrawer" to-id="first-item-node-layout-target"
  140. uis="hc-first-item-node-layout" @close="FirstReportDrawerClose"
  141. >
  142. <div class="node-content">
  143. <div class="node-form">
  144. <el-scrollbar v-if="contractId && isTableForm" ref="ListItemScrollRef">
  145. <!-- <div class="hc-excel-table-form-view" :id="`table-form-${contractId}`"></div> -->
  146. <ListItem
  147. ref="ListItemsRef"
  148. :classify="authBtnTabKey"
  149. :contract-id="contractId"
  150. :datas="ListItemDatas"
  151. :draw-type="isDrawType"
  152. :finish-file="finishFile"
  153. :project-info="projectInfo"
  154. :status="NodeStatus"
  155. :table-file-data="tableFileData"
  156. :tree-item="treeItem"
  157. @offset-top="ListItemOffsetTop"
  158. @renew="renewtable"
  159. />
  160. </el-scrollbar>
  161. <HcStatus v-else :desc="statusDesc" />
  162. </div>
  163. <div class="node-file">
  164. <div class="title">上传总结报告1111</div>
  165. <div v-if="contractId && isTableForm" class="node-upload-box">
  166. <HcUpload :file-list="fileListData" :pkey-id="pkeyIds" @finish="uploadChange" />
  167. </div>
  168. <div v-else class="node-upload-box">
  169. <el-alert :closable="false" show-icon title="表单异常,暂时无法使用上传" type="warning" />
  170. </div>
  171. <el-divider border-style="dashed" />
  172. <div class="title">文件附件</div>
  173. <div class="hc-table-node-file-box">
  174. <HcTable :column="tableFileColumn" :datas="tableFileData" :is-index="false" is-new>
  175. <template #action="{ row, index }">
  176. <el-button plain size="small" type="danger" @click="tableDelButton(index)">
  177. 删除
  178. </el-button>
  179. </template>
  180. </HcTable>
  181. </div>
  182. </div>
  183. </div>
  184. <div class="node-action">
  185. <el-button
  186. :disabled="!contractId || !isTableForm || NodeStatus === '3'" :loading="tableFormSaveLoading"
  187. hc-btn
  188. type="primary" @click="saveBussData"
  189. >
  190. <HcIcon name="save" />
  191. <span>保存</span>
  192. </el-button>
  193. <el-button
  194. :disabled="!contractId || !isTableForm || !tableFormId || NodeStatus === '1'" hc-btn
  195. @click="bussPdfInfo"
  196. >
  197. <HcIcon name="eye" />
  198. <span>预览</span>
  199. </el-button>
  200. <el-button
  201. :disabled="!contractId || !isTableForm || !tableFormId || NodeStatus === '3' || NodeStatus === '1'"
  202. :loading="reportLoading"
  203. hc-btn @click="reportModalClick(2)"
  204. >
  205. <HcIcon name="send-plane-2" />
  206. <span>上报</span>
  207. </el-button>
  208. <el-button hc-btn @click="FirstReportDrawerClose">
  209. <HcIcon name="close" />
  210. <span>返回</span>
  211. </el-button>
  212. </div>
  213. </HcDrawer>
  214. <!-- 上报审批 -->
  215. <HcReportModal
  216. :contract-id="contractId"
  217. :datas="reportDatas"
  218. :ids="reportIds"
  219. :is-datas="isReportModalDatas"
  220. :project-id="projectId"
  221. :show="showReportModal"
  222. :task-name="reportTaskName"
  223. :type-data="reportTypeData"
  224. title="上报审批"
  225. type="first"
  226. url="informationWriteQuery/batchTask"
  227. @finish="showReportFinish"
  228. @hide="showReportModal = false"
  229. @tag-close="reportTaskTagClose"
  230. />
  231. </div>
  232. </template>
  233. <script setup>
  234. import { useAppStore } from '~src/store'
  235. import { nextTick, onMounted, ref, watch } from 'vue'
  236. import { useRoute, useRouter } from 'vue-router'
  237. import WbsTree from './components/WbsTree.vue'
  238. import HcUpload from './components/HcUpload.vue'
  239. import HTableForm from '~src/plugins/HTableForm'
  240. import { eVisaTaskCheckApi, getReportNumber } from '~api/other'
  241. import firstApi from '~api/other/first-item'
  242. import tasksApi from '~api/tasks/data'
  243. import { getStoreValue, setStoreValue } from '~src/utils/storage'
  244. import { arrToId, deepClone, getArrValue, getObjVal, getObjValue, isString } from 'js-fast-way'
  245. import queryApi from '~api/data-fill/query'
  246. import wbsApi from '~api/data-fill/wbs'
  247. import ListItem from './components/ListItem.vue'
  248. import { delMessageV2 } from '~com/message/index.js'
  249. import { toPdfPage } from '~uti/btn-auth'
  250. //变量
  251. const router = useRouter()
  252. const useRoutes = useRoute()
  253. const useAppState = useAppStore()
  254. const projectId = ref(useAppState.getProjectId)
  255. const contractId = ref(useAppState.getContractId)
  256. const projectInfo = ref(useAppState.getProjectInfo)
  257. const contractInfo = ref(useAppState.getContractInfo)
  258. const isCollapse = ref(useAppState.getCollapse)
  259. //路由参数
  260. const routerQuery = useRoutes?.query
  261. const typeName = routerQuery?.type || 'mark'
  262. //监听
  263. watch(() => [
  264. useAppState.getCollapse,
  265. ], ([Collapse]) => {
  266. isCollapse.value = Collapse
  267. })
  268. //自动展开缓存
  269. const TreeAutoExpandKeys = ref(getStoreValue('firstItemTreeKeys') || [])
  270. //类型tab数据和相关处理
  271. const tabTypeKey = ref(typeName)
  272. const tabTypeTab = ref([
  273. { key: 'mark', name: '已标记为首件' },
  274. { key: 'query', name: '首件查询' },
  275. ])
  276. const tabTypeChange = (item) => {
  277. tableFormId.value = ''
  278. tabTypeKey.value = item?.key
  279. if (searchForm.value.wbsId) {
  280. searchForm.value.current = 1
  281. getTableData()
  282. }
  283. //路由跳转
  284. router.push({
  285. path: useRoutes.path,
  286. query: { type: item?.key },
  287. })
  288. }
  289. //渲染完成
  290. onMounted(() => {
  291. firstTaskStatus()
  292. })
  293. const renewtable = () => {
  294. getTableData()
  295. queryNodeStatus()
  296. }
  297. //项目树被点击
  298. const treeItem = ref({})
  299. const nodeWbsElTreeClick = ({ data, keys }) => {
  300. treeItem.value = data
  301. searchForm.value.contractIdRelation = data['contractIdRelation']
  302. searchForm.value.wbsId = data['primaryKeyId']
  303. //缓存自动展开
  304. TreeAutoExpandKeys.value = keys
  305. setStoreValue('firstItemTreeKeys', keys)
  306. //获取相关数据
  307. getReportNumberByContractId(data['contractIdRelation'])
  308. searchClick()
  309. }
  310. //获取流程状态
  311. const processStatus = ref([])
  312. const firstTaskStatus = async () => {
  313. const { data } = await tasksApi.queryTaskTypeStatus({
  314. typeOrStatus: 'first_task_status',
  315. })
  316. //处理数据
  317. processStatus.value = getArrValue(data)
  318. }
  319. //查询状态
  320. const NodeStatus = ref('1')
  321. const { contractType } = contractInfo.value
  322. const authBtnTabKey = ref(contractType === 2 ? '2' : '1')
  323. const queryNodeStatus = async () => {
  324. const info = treeItem.value
  325. console.log(info, 'info')
  326. const { error, code, data } = await wbsApi.queryNodeStatus({
  327. // primaryKeyId: info['contractIdRelation'] ? info['id'] : info['primaryKeyId'],
  328. // classify: 1
  329. primaryKeyId: authBtnTabKey.value == 1 ? info['id'] : info['primaryKeyId'],
  330. classify: authBtnTabKey.value,
  331. })
  332. //1 未填报,2待上报,3已上报
  333. if (!error && code === 200) {
  334. NodeStatus.value = data ?? '1'
  335. } else {
  336. NodeStatus.value = '1'
  337. }
  338. }
  339. //获取上报批次
  340. const reportBatch = ref([])
  341. const getReportNumberByContractId = async (cid) => {
  342. const { data } = await getReportNumber({
  343. contractId: contractId.value,
  344. projectId: projectId.value,
  345. contractIdRelation: cid ?? '',
  346. firstTitle: tabTypeKey.value === 'query' ? 1 : null,
  347. })
  348. //处理数据
  349. reportBatch.value = getArrValue(data)
  350. }
  351. //搜索表单
  352. const searchForm = ref({
  353. wbsId: '', status: null, reportNumber: null, queryValue: '', betweenTime: '',
  354. contractIdRelation: '', current: 1, size: 20, total: 0,
  355. })
  356. //日期时间被选择
  357. const betweenTime = ref(null)
  358. const betweenTimeUpdate = ({ query, arr }) => {
  359. betweenTime.value = arr
  360. searchForm.value.betweenTime = query
  361. }
  362. //回车搜索
  363. const keyUpEvent = (e) => {
  364. if (e.key === 'Enter') {
  365. searchClick()
  366. }
  367. }
  368. //搜索
  369. const searchClick = () => {
  370. if (searchForm.value.wbsId) {
  371. searchForm.value.current = 1
  372. getTableData()
  373. } else {
  374. window?.$message?.warning('请先在左边选择一个树节点')
  375. }
  376. }
  377. //分页被点击
  378. const pageChange = ({ current, size }) => {
  379. searchForm.value.current = current
  380. searchForm.value.size = size
  381. getTableData()
  382. }
  383. //表格表头
  384. const tableListColumn = ref([
  385. { key: 'name', name: '文件名称' },
  386. { key: 'waitingUserList', name: '任务人' },
  387. { key: 'startTime', name: '开始时间', width: 180 },
  388. { key: 'taskStatusStr', name: '流程状态', width: 140 },
  389. { key: 'reportNumber', name: '上报批次', width: 120 },
  390. ])
  391. //获取表格数据
  392. const tableLoading = ref(false)
  393. const tableListData = ref([])
  394. //获取数据列表
  395. const ListItemsRef = ref(null)
  396. //是否是抽屉
  397. const isDrawType = ref(false)
  398. //设置滚动条位置
  399. const ListItemScrollRef = ref(null)
  400. const ListItemOffsetTop = (offsetTop) => {
  401. if (offsetTop > 0) {
  402. setTimeout(() => {
  403. ListItemScrollRef.value?.setScrollTop(offsetTop)
  404. }, 350)
  405. } else {
  406. ListItemScrollRef.value?.setScrollTop(offsetTop)
  407. }
  408. }
  409. const getTableData = async () => {
  410. const searchInfo = searchForm.value
  411. const tabKey = tabTypeKey.value
  412. if (searchInfo.wbsId) {
  413. //初始处理
  414. tableLoading.value = true
  415. tableListRef.value?.clearSelection()
  416. tableSelectionKeys.value = []
  417. tableListData.value = []
  418. //获取相关数据
  419. let addFormData = {
  420. projectId: projectId.value,
  421. contractId: contractId.value,
  422. isFirst: 1,
  423. }
  424. const treeInfo = treeItem.value
  425. //已标记的首件
  426. if (tabKey === 'mark' && addFormData['firstTitle']) {
  427. delete addFormData.firstTitle
  428. }
  429. //查询数据
  430. if (tabKey === 'query') {
  431. addFormData['firstTitle'] = 1
  432. }
  433. addFormData['wbsId'] = treeInfo['contractIdRelation'] ? treeInfo['id'] : treeInfo['primaryKeyId']
  434. //处理数据
  435. const { error, code, data } = await firstApi.getQueryPageData({
  436. ...addFormData,
  437. ...searchInfo,
  438. })
  439. tableLoading.value = false
  440. if (!error && code === 200) {
  441. tableListData.value = getArrValue(data['records'])
  442. searchForm.value.total = data.total || 0
  443. } else {
  444. tableListData.value = []
  445. searchForm.value.total = 0
  446. }
  447. } else {
  448. window?.$message?.warning('请先选择一个树节点')
  449. }
  450. }
  451. //多选
  452. const tableListRef = ref(null)
  453. const tableSelectionKeys = ref([])
  454. const tableSelectionChange = (rows) => {
  455. tableSelectionKeys.value = rows.filter((item) => {
  456. return (item ?? '') !== ''
  457. })
  458. }
  459. //文件名称被点击
  460. const tableRowName = (row) => {
  461. //如果 evisaPdfUrl 不为空,使用evisaPdfUrl,反之使用pdfUrl
  462. if (tabTypeKey.value === 'query') {
  463. //首件查询时,直接调用接口
  464. getBussPdfInfo(row.id + '')
  465. } else if (row['evisaPdfUrl']) {
  466. toPdfPage(row['evisaPdfUrl'])
  467. //window.open(row['evisaPdfUrl'], '_blank')
  468. } else if (row['pdfUrl']) {
  469. toPdfPage(row['pdfUrl'])
  470. //window.open(row['pdfUrl'], '_blank')
  471. } else {
  472. window.$message?.warning('文件不存在')
  473. }
  474. }
  475. const ListItemDatas = ref([])
  476. //上报首件
  477. const isFirstReportDrawer = ref(false)
  478. const isCanreport = ref(false)
  479. const firstReportClick = () => {
  480. const rows = deepClone(tableSelectionKeys.value)
  481. console.log(rows, 'rows')
  482. nextTick(() => {
  483. ListItemDatas.value = rows
  484. })
  485. console.log(ListItemDatas.value, ' ListItemDatas.value')
  486. //判断是否满足条件
  487. const result = rows.every(({ status }) => {
  488. return status === 2
  489. // return status === 0 || status === 3
  490. })
  491. isCanreport.value = result
  492. //判断状态
  493. // if (result) {
  494. // isFirstReportDrawer.value = true
  495. // queryNodeStatus()
  496. // tableFileData.value = rows
  497. // getFirstExcelHtml()
  498. // } else {
  499. // tableFileData.value = []
  500. // window.$message?.warning('已上报的文件不能进行再次上报,若要重新上报,要先撤回之前的上报,再重新上报')
  501. // }
  502. isFirstReportDrawer.value = true
  503. // getTableData()
  504. queryNodeStatus()
  505. tableFileData.value = rows
  506. getFirstExcelHtml()
  507. }
  508. const FirstReportDrawerClose = () => {
  509. isFirstReportDrawer.value = false
  510. }
  511. //获取表单
  512. const statusDesc = ref('')
  513. const isTableForm = ref(false)
  514. const pkeyIds = ref('')
  515. const getFirstExcelHtml = async () => {
  516. const cid = contractId.value
  517. const { error, code, data } = await firstApi.getFirstExcelHtml({
  518. contractId: contractId.value || '',
  519. }, false)
  520. //处理数据
  521. const temp = isString(data?.data) ? data?.data || '' : ''
  522. if (!error && code === 200 && temp) {
  523. let pkeyId = data?.id || ''
  524. pkeyIds.value = pkeyId
  525. await getFirstBussDataInfo(pkeyId)
  526. setHTableForm(temp, cid)
  527. } else {
  528. isTableForm.value = false
  529. statusDesc.value = '暂无表单'
  530. window?.$message?.warning('暂无表单')
  531. }
  532. }
  533. //渲染表单
  534. const tableFormApp = ref(null)
  535. const setHTableForm = (resData, cid) => {
  536. //先卸载
  537. if (tableFormApp.value) {
  538. tableFormApp.value?.unmount()
  539. }
  540. if (resData) {
  541. isTableForm.value = true
  542. nextTick(() => {
  543. tableFormApp.value = HTableForm.createForm({
  544. template: resData,
  545. tableForm: tableFormData.value,
  546. appId: `#table-form-${cid}`,
  547. })
  548. })
  549. } else {
  550. isTableForm.value = false
  551. statusDesc.value = '暂无表单'
  552. window?.$message?.warning('暂无表单')
  553. }
  554. }
  555. //获取回显数据
  556. const tableFormData = ref({})
  557. const getFirstBussDataInfo = async (pkeyId) => {
  558. if (pkeyId) {
  559. const { data } = await firstApi.getFirstBussDataInfo({
  560. contractId: contractId.value || '',
  561. firstId: pkeyId + '',
  562. }, false)
  563. const info = getObjValue(data)
  564. if (getObjVal(info)) {
  565. HTableForm.setPickerKey(info)
  566. tableFormData.value = info
  567. } else {
  568. tableFormData.value = {}
  569. }
  570. } else {
  571. tableFormData.value = {}
  572. }
  573. }
  574. //上传变量
  575. const fileListData = ref([])
  576. const finishFile = ref({
  577. sourceUrl: '', pdfUrl: '', firstFileName: '',
  578. })
  579. //上传文件
  580. const uploadChange = async ({ type, res }) => {
  581. if (type === 'success') {
  582. const { code, data, msg } = res
  583. if (code === 200) {
  584. finishFile.value = {
  585. sourceUrl: data?.sourceUrl,
  586. pdfUrl: data?.pdfUrl,
  587. firstFileName: data?.fileName,
  588. }
  589. window.$message?.success(msg)
  590. } else {
  591. window.$message?.error(msg || '上传失败')
  592. }
  593. }
  594. }
  595. //文件附件列表
  596. const tableFileColumn = ref([
  597. { key: 'name', name: '文件名称' },
  598. { key: 'action', name: '操作', width: 80, align: 'center' },
  599. ])
  600. const tableFileData = ref([])
  601. const tableDelButton = (index) => {
  602. const arr = tableFileData.value
  603. if (arr.length > 1) {
  604. delMessageV2(async (action, instance, done) => {
  605. if (action === 'confirm') {
  606. instance.confirmButtonLoading = true
  607. tableFileData.value.splice(index, 1)
  608. instance.confirmButtonLoading = false
  609. done()
  610. } else {
  611. done()
  612. }
  613. })
  614. } else {
  615. window?.$message?.warning('至少保留一个文件')
  616. }
  617. }
  618. //填报数据保存
  619. const pdfId = ref('')
  620. const saveBussData = async () => {
  621. console.log('保存')
  622. const { id } = treeItem.value
  623. const res = await saveExcelBussData(id + '')
  624. //刷新页面
  625. // window?.location?.reload() //刷新页面
  626. if (res) {
  627. pdfId.value = res
  628. queryNodeStatus()
  629. await getBussPdfInfo(res)
  630. }
  631. }
  632. //保存请求
  633. const tableFormSaveLoading = ref(false)
  634. const tableFormId = ref('')
  635. const saveExcelBussData = async (pkeyId) => {
  636. tableFormId.value = ''
  637. const { primaryKeyId } = treeItem.value
  638. tableFormSaveLoading.value = true
  639. const linkIds = rowsToArr(tableFileData.value)
  640. const { error, code, data } = await firstApi.saveBussData({
  641. ...tableFormData.value,
  642. projectId: projectId.value,
  643. contractId: contractId.value,
  644. firstNodeId: primaryKeyId,
  645. pkeyId: pkeyId,
  646. classify: '1',
  647. isFirst: 1,
  648. linkProcessList: linkIds,
  649. ...finishFile.value,
  650. }, false)
  651. //判断状态
  652. tableFormSaveLoading.value = false
  653. if (!error && code === 200 && isString(data)) {
  654. window.$message?.success('保存成功')
  655. tableFormId.value = data
  656. return data
  657. } else {
  658. window.$message?.error('保存失败')
  659. tableFormId.value = ''
  660. return ''
  661. }
  662. }
  663. //pdf预览
  664. const bussPdfInfo = () => {
  665. const { id } = treeItem.value
  666. // getBussPdfInfo(id + '')
  667. getBussPdfInfo(pdfId.value)
  668. }
  669. //预览PDF请求
  670. const getBussPdfInfo = async (pkeyId) => {
  671. const { error, code, data } = await firstApi.getFirstBussPdfInfo({
  672. firstId: pkeyId,
  673. })
  674. //判断状态
  675. const res = isString(data) ? data ?? '' : ''
  676. if (!error && code === 200 && res) {
  677. toPdfPage(res)
  678. //window.open(res, '_blank')
  679. }
  680. }
  681. //上报审批
  682. const reportIds = ref('')
  683. const showReportModal = ref(false)
  684. const reportTaskName = ref('')
  685. const reportAddition = ref({})
  686. const reportLoading = ref(false)
  687. const reportTypeData = ref('')
  688. const reportDatas = ref([])
  689. const isReportModalDatas = ref(false)
  690. const iscanReport = ref(false)
  691. //上报方法封装
  692. const toreportModalClick = async (type) => {
  693. if (type) {
  694. const { primaryKeyId, contractIdRelation } = treeItem.value
  695. let rows = []
  696. //处理获取流程的条件
  697. if (tabTypeKey.value === 'mark') {
  698. reportTypeData.value = tableFormId.value
  699. isReportModalDatas.value = false
  700. rows = tableFileData.value
  701. } else {
  702. isReportModalDatas.value = true
  703. rows = tableSelectionKeys.value
  704. }
  705. if (rows.length > 0) {
  706. reportLoading.value = true
  707. const taskCheck = await eVisaTaskCheckApi({
  708. projectId: projectId.value,
  709. contractId: contractId.value,
  710. })
  711. if (taskCheck) {
  712. if (tabTypeKey.value === 'mark') {
  713. reportIds.value = tableFormId.value
  714. const { data } = await firstApi.queryFirstDocumentTitle({
  715. projectId: projectId.value,
  716. contractId: contractId.value,
  717. queryId: tableFormId.value,
  718. })
  719. reportTaskName.value = isString(data) ? data ?? '' : ''
  720. } else {
  721. reportIds.value = arrToId(rows)
  722. //设置任务数据
  723. let reportDataArr = []
  724. rows.forEach(item => {
  725. reportDataArr.push({
  726. id: item?.id,
  727. name: item?.name,
  728. })
  729. })
  730. reportDatas.value = reportDataArr
  731. //其他数据
  732. reportTypeData.value = rows[0]['id']
  733. reportTaskName.value = rows.length > 1 ? `${rows[0].name}等${rows.length}个文件` : rows[0].name
  734. }
  735. reportLoading.value = false
  736. //附加数据
  737. reportAddition.value = {
  738. classify: 1,
  739. isFirst: 1,
  740. primaryKeyId: primaryKeyId,
  741. contractIdRelation: contractIdRelation ?? contractId.value,
  742. }
  743. showReportModal.value = true
  744. } else {
  745. reportLoading.value = false
  746. }
  747. } else {
  748. window.$message?.warning('暂无相关数据')
  749. }
  750. } else {
  751. window.$message?.warning('当前工序资料还未审批,待审批完成才能进行首件模板上报')
  752. }
  753. }
  754. const reportModalClick = async (type) => {
  755. if (type === 2) {
  756. console.log('上报')
  757. iscanReport.value = isCanreport.value
  758. toreportModalClick(iscanReport.value)
  759. } else {
  760. const rows = deepClone(tableSelectionKeys.value)
  761. let result = false
  762. console.log('上报审批', rows)
  763. //判断自身是否满足条件
  764. const result1 = rows.every(({ taskStatusStr }) => {
  765. return taskStatusStr === '未上报' || taskStatusStr === '已废除'
  766. })
  767. if (result1) {
  768. //判断工序节点是否满足条件
  769. result = rows.every(({ isApprove }) => {
  770. return isApprove === true
  771. })
  772. iscanReport.value = result
  773. toreportModalClick(iscanReport.value)
  774. } else {
  775. window.$message?.warning('已上报的数据不能重复上报')
  776. iscanReport.value = false
  777. }
  778. }
  779. }
  780. //上报的审批内容移除
  781. const reportTaskTagClose = (index) => {
  782. const row = tableSelectionKeys.value[index]
  783. tableListRef.value?.toggleRowSelection(row, false)
  784. }
  785. const getTableDataAll = () => {
  786. getTableData()
  787. firstTaskStatus()
  788. }
  789. //上报完成
  790. const showReportFinish = () => {
  791. showReportModal.value = false
  792. getTableDataAll()
  793. }
  794. //打印
  795. const printLoading = ref(false)
  796. const batchPrint = async () => {
  797. const rows = tableSelectionKeys.value
  798. const ids = arrToId(rows)
  799. //批量下载
  800. printLoading.value = true
  801. const { error, code, data } = await firstApi.batchPrint({
  802. ids: ids,
  803. })
  804. //处理数据
  805. printLoading.value = false
  806. //判断状态
  807. const res = isString(data) ? data ?? '' : ''
  808. if (!error && code === 200 && res) {
  809. toPdfPage(res)
  810. //window.open(res, '_blank')
  811. }
  812. }
  813. //废除
  814. const batchAbolishClick = () => {
  815. const rows = tableSelectionKeys.value
  816. //判断是否满足条件
  817. const result = rows.every(({ status }) => {
  818. return status !== 0 && status !== 3
  819. })
  820. //判断状态
  821. if (result) {
  822. //拼接ID
  823. const ids = arrToId(rows)
  824. window?.$messageBox?.alert('是否废除勾选的已上报文件?', '废除文件', {
  825. showCancelButton: true,
  826. confirmButtonText: '确定废除',
  827. cancelButtonText: '取消',
  828. callback: (action) => {
  829. if (action === 'confirm') {
  830. batchAbolishSave(ids)
  831. }
  832. },
  833. })
  834. } else {
  835. window.$message?.warning('未上报的文件不能废除')
  836. }
  837. }
  838. //废除勾选的已上报文件
  839. const batchAbolishSave = async (ids) => {
  840. const { error, code } = await queryApi.batchAbolish({ ids: ids, projectId:projectId.value, contractId:contractId.value })
  841. //处理数据
  842. if (!error && code === 200) {
  843. window.$message?.success('批量废除成功')
  844. tableSelectionKeys.value = []
  845. getTableData()
  846. }
  847. }
  848. //处理数据
  849. const rowsToArr = (rows) => {
  850. let newArr = []
  851. for (let i = 0; i < rows.length; i++) {
  852. newArr.push({
  853. id: rows[i]?.id,
  854. name: rows[i]?.name,
  855. })
  856. }
  857. return newArr
  858. }
  859. //左右拖动,改变树形结构宽度
  860. const leftWidth = ref(382)
  861. const onmousedown = () => {
  862. const leftNum = isCollapse.value ? 142 : 272
  863. document.onmousemove = (ve) => {
  864. const diffVal = ve.clientX - leftNum
  865. if (diffVal >= 310 && diffVal <= 900) {
  866. leftWidth.value = diffVal
  867. }
  868. }
  869. document.onmouseup = () => {
  870. document.onmousemove = null
  871. document.onmouseup = null
  872. }
  873. }
  874. </script>
  875. <style lang="scss" scoped>
  876. @import "../../styles/other/first-item.scss";
  877. </style>
  878. <style lang="scss">
  879. .hc-first-item-node-layout.el-overlay {
  880. position: absolute;
  881. background-color: transparent;
  882. margin: -24px;
  883. height: revert;
  884. .hc-drawer-box.el-drawer {
  885. --el-drawer-bg-color: transparent;
  886. .el-drawer__body {
  887. padding: 24px;
  888. display: flex;
  889. flex-direction: column;
  890. overflow: hidden;
  891. }
  892. }
  893. }
  894. </style>