first-item.vue 32 KB

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