hc-data.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516
  1. <template>
  2. <div class="hc-layout-box">
  3. <HcTabsSimple :cur="sbTableKey" :datas="sbTableData" :no-drop-shadow="showTaskReviewModal" @tab-click="sbTableClick">
  4. <template #tab-key1>
  5. <TableCard
  6. v-if="sbTableKey === 'key1'" :contract-id="contractId"
  7. :contract-list="contractList"
  8. :project-id="projectId" :table-key="sbTableKey"
  9. @batch-approval="batchApprovalTaskClick" @row-task-name="rowTaskName"
  10. @sign-rules="setSignRulesClick"
  11. />
  12. </template>
  13. <template #tab-key2>
  14. <TableCard
  15. v-if="sbTableKey === 'key2'" :contract-id="contractId"
  16. :contract-list="contractList"
  17. :project-id="projectId" :table-key="sbTableKey"
  18. @batch-approval="batchApprovalTaskClick" @row-task-name="rowTaskName"
  19. @sign-rules="setSignRulesClick"
  20. />
  21. </template>
  22. <template #tab-key3>
  23. <TableCard
  24. v-if="sbTableKey === 'key3'" :contract-id="contractId"
  25. :contract-list="contractList"
  26. :project-id="projectId" :table-key="sbTableKey"
  27. @batch-approval="batchApprovalTaskClick" @row-task-name="rowTaskName"
  28. @sign-rules="setSignRulesClick"
  29. />
  30. </template>
  31. </HcTabsSimple>
  32. <!-- 任务审核 -->
  33. <hc-dialog v-model="showTaskReviewModal" ui="hc-modal-border hc-modal-table" is-table widths="98vw">
  34. <template #header="{ titleId, titleClass }">
  35. <div class="hc-card-header flex items-center">
  36. <div :id="titleId" :class="titleClass">任务审核 【已开启电签】</div>
  37. <div v-if="taskReviewType === '1'" class="text-main ml-6 font-bold">任务名称:{{ taskReviewInfo.taskName }}</div>
  38. </div>
  39. </template>
  40. <div class="hc-card-body-flex">
  41. <div v-if="batchPdfUrl" class="flex-iframe">
  42. <!-- <HcPdf :src="batchPdfUrl" @change="changeSealStrategy" /> -->
  43. <template v-if="sbTableKey === 'key1'">
  44. <HcSignPdf v-if="pdfItem.pdfUrl" :batch="isBatch" :dom="pdfItem.hcSignImageArr" :sign="logoName" :src="pdfItem.pdfUrl" @change="pdfChange" />
  45. </template>
  46. <hc-pdfs v-else :src="pdfItem.pdfUrl" />
  47. </div>
  48. <div v-else class="flex-iframe hc-no-table-form">
  49. <div class="table-form-no">
  50. <img :src="notableform" alt="">
  51. <div class="desc">暂无 PDF 数据</div>
  52. </div>
  53. </div>
  54. <div :class="sbTableKey === 'key1' ? '' : 'vh'" class="flex-table">
  55. <el-button v-if="sbTableKey === 'key1' && !isBatch && isShowDqBtn" class="mb-4" hc-btn type="warning" @click="BatchClick(true)">批量电签</el-button>
  56. <el-button v-if="sbTableKey === 'key1' && isBatch && isShowDqBtn" class="mb-4" hc-btn type="warning" @click="BatchClick(false)">取消批量签名/章</el-button>
  57. <div v-if="taskReviewType === '1'" class="data-table taskReviewData">
  58. <HcTable :column="taskReviewColumns" :datas="taskReviewData" :index-style="{ width: 60 }" is-new @row-click="rowTaskReviewClick" />
  59. </div>
  60. <div v-if="taskReviewType === '2'" class="data-table checkedRowsRef">
  61. <HcTable :column="checkedRowsColumns" :datas="checkedRowsRef" :index-style="{ width: 60 }" is-new @row-click="rowTaskReviewClick" />
  62. </div>
  63. <div v-if="sbTableKey === 'key1'" class="radio-group-box">
  64. <span class="label">审批操作:</span>
  65. <el-radio-group v-model="taskReviewForm.flag">
  66. <el-radio value="OK">同意</el-radio>
  67. <el-radio value="NO">废除任务</el-radio>
  68. </el-radio-group>
  69. </div>
  70. <div v-if="sbTableKey === 'key1'" class="textarea-box">
  71. <el-input v-model="taskReviewForm.comment" :autosize="{ minRows: 3, maxRows: 5 }" placeholder="请输入审核意见" type="textarea" />
  72. </div>
  73. </div>
  74. </div>
  75. <template v-if="sbTableKey === 'key1'" #footer>
  76. <div class="dialog-footer">
  77. <el-button size="large" @click="showTaskReviewModal = false">取消</el-button>
  78. <el-button :loading="SMSAuthLoading" hc-btn type="primary" @click="ConfirmApprovalClick">确认审批</el-button>
  79. </div>
  80. </template>
  81. </hc-dialog>
  82. <!-- 设置重签规则 -->
  83. <el-dialog v-model="showSetSignRulesModal" ui="hc-modal-border" title="设置重签规则" width="38rem">
  84. <div class="mb-10 text-orange">
  85. <span class="mr-4">提示:设置默认时长,在任务被废除需要重签的时候,规定的重签上报时间提示时间段内,系统提示用户重签信息,但是超过处理时间,系统可默认自动授权重签</span>
  86. <el-checkbox v-model="setPactVal" value="Option 1" size="large">
  87. <span class="text-main">《授权系统自动电签协议》</span>
  88. </el-checkbox>
  89. </div>
  90. <div class="obj-item-cell">
  91. <div class="label">默认处理时间(时)</div>
  92. <HcCounter v-model="formReport.date" @update:model-value="dateUpdateValue" />
  93. </div>
  94. <div class="obj-item-cell">
  95. <div class="label">开启系统自动电签</div>
  96. <el-switch v-model="formReport.active" />
  97. </div>
  98. <template #footer>
  99. <div class="dialog-footer">
  100. <el-button size="large" @click="showSetSignRulesModal = false">取消</el-button>
  101. <el-button hc-btn type="primary">保存</el-button>
  102. </div>
  103. </template>
  104. </el-dialog>
  105. <!-- 短信认证 -->
  106. <HcSmsAuth :loading="SMSAuthLoading" :show="SMSAuthShow" @cancel="SMSAuthCancel" @confirm="SMSAuthConfirm" />
  107. </div>
  108. </template>
  109. <script setup>
  110. import { nextTick, onMounted, ref } from 'vue'
  111. import { useAppStore } from '~src/store'
  112. import { useRoute, useRouter } from 'vue-router'
  113. import TableCard from './components/TableCard.vue'
  114. import notableform from '~src/assets/view/notableform.svg'
  115. import { getContractInfo } from '~api/other'
  116. import { arrToKey, getArrValue, isString } from 'js-fast-way'
  117. import HcSignPdf from './components/hc-pdf1.vue'
  118. import tasksApi from '~api/tasks/data'
  119. import dayjs from 'dayjs'
  120. import userApi from '~api/userInfo/index'
  121. //初始变量
  122. const router = useRouter()
  123. const useRoutes = useRoute()
  124. const useAppState = useAppStore()
  125. //路由参数
  126. const routerQuery = useRoutes?.query
  127. const activeName = routerQuery?.active || 'key1'
  128. //全局变量
  129. const projectId = ref(useAppState.getProjectId)
  130. const contractId = ref(useAppState.getContractId)
  131. const projectInfo = ref(useAppState.getProjectInfo)
  132. //渲染完成
  133. onMounted(() => {
  134. checkSmsCode()
  135. getContractInfoList()
  136. })
  137. //pdf
  138. //合同段信息
  139. const contractList = ref([])
  140. const getContractInfoList = async () => {
  141. const { error, code, data } = await getContractInfo({
  142. pid: projectId.value,
  143. })
  144. if (!error && code === 200) {
  145. contractList.value = getArrValue(data)
  146. } else {
  147. contractList.value = []
  148. }
  149. }
  150. //类型处理
  151. const sbTableKey = ref(activeName)
  152. const sbTableData = ref([
  153. { icon: 'time', label: '待办任务', key: 'key1' },
  154. { icon: 'calendar-check', label: '已办任务', key: 'key2' },
  155. { icon: 'user-shared', label: '我发起的', key: 'key3' },
  156. ])
  157. const sbTableClick = (key) => {
  158. sbTableKey.value = key
  159. router.push({
  160. path: useRoutes.path,
  161. query: { active: key },
  162. })
  163. }
  164. //审批页详情
  165. const showTaskReviewModal = ref(false)
  166. const taskReviewType = ref('1')
  167. const taskReviewInfo = ref({})
  168. const taskReviewData = ref([])
  169. const batchPdfUrl = ref('')
  170. const taskReviewForm = ref({ flag: 'OK', comment: '' })
  171. const taskReviewColumns = ref([
  172. { key: 'fileName', name: '文件名称' },
  173. ])
  174. const pdfItem = ref({})
  175. const pdfIndex = ref(-1)
  176. const logoName = ref('')
  177. //获取用户信息
  178. const queryCurrentUserData = async () => {
  179. const { error, code, data } = await userApi.queryCurrentUserData()
  180. if (!error && code === 200) {
  181. logoName.value = data?.signatureUrl || ''
  182. } else {
  183. logoName.value = ''
  184. }
  185. }
  186. const pdfDataClick = (item, index) => {
  187. pdfItem.value = {}
  188. pdfIndex.value = index
  189. nextTick(() => {
  190. pdfItem.value = item
  191. })
  192. }
  193. const signArr = ref([])
  194. //签章数据改变
  195. const pdfChange = (data) => {
  196. console.log('签章数据', data)
  197. // pdfData.value[pdfIndex.value].hcSignImageArr = data
  198. if (taskReviewType.value === '2') {
  199. checkedRowsRef.value.forEach((ele) => {
  200. if (ele.id === pdfIndex.value) {
  201. ele.hcSignImageArr = data
  202. }
  203. })
  204. } else {
  205. signArr.value = data
  206. }
  207. }
  208. const isBatch = ref(false)
  209. const BatchClick = (val) => {
  210. isBatch.value = val
  211. }
  212. const isShowDqBtn = ref(true)
  213. //任务审核
  214. const rowTaskName = async (row) => {
  215. // if (row.id && row.type !== 2) {
  216. if (row.type !== 2) {
  217. isShowDqBtn.value = true
  218. } else {
  219. isShowDqBtn.value = false
  220. }
  221. taskReviewInfo.value = row
  222. const { error, code, data } = await tasksApi.queryTaskInfo({
  223. taskIds: row.id,
  224. type: row.type,
  225. })
  226. if (!error && code === 200) {
  227. const approvalFileList = getArrValue(data)
  228. taskReviewData.value = approvalFileList
  229. if (approvalFileList.length > 0) {
  230. batchPdfUrl.value = approvalFileList[0].pdfUrl
  231. if (sbTableKey.value === 'key1' && row.type !== 2) {
  232. queryCurrentUserData()
  233. } else {
  234. logoName.value = ''
  235. }
  236. pdfItem.value.pdfUrl = approvalFileList[0].pdfUrl
  237. }
  238. taskReviewType.value = '1'
  239. showTaskReviewModal.value = true
  240. isBatch.value = false
  241. } else {
  242. taskReviewData.value = []
  243. batchPdfUrl.value = ''
  244. }
  245. // } else {
  246. // taskReviewInfo.value = {}
  247. // taskReviewData.value = []
  248. // batchPdfUrl.value = ''
  249. // // window?.$message?.warning('此数据异常')
  250. // }
  251. }
  252. //批量审批
  253. const checkedRowsColumns = ref([
  254. { key: 'taskName', name: '任务名称' },
  255. ])
  256. const checkedRowsRef = ref([])
  257. const taskId = ref([])
  258. const batchApprovalTaskClick = (rows) => {
  259. //不同任务类型不能一起批量审批
  260. let types = arrToKey(rows, 'type', ',').split(',')
  261. let newTypes = Array.from(new Set(types))
  262. if (newTypes.length > 1) {
  263. window.$message.warning('不同任务类型不能一起批量审批')
  264. } else {
  265. taskReviewType.value = '2'
  266. showTaskReviewModal.value = true
  267. isBatch.value = false
  268. checkedRowsRef.value = rows
  269. let taskids = []
  270. rows.forEach((item) => {
  271. taskids.push(item.id)
  272. })
  273. taskids = taskids.join()
  274. queryTaskInfo(rows[0], taskids)
  275. }
  276. }
  277. //行被点击
  278. const rowTaskReviewClick = async ({ row }) => {
  279. console.log(row, 'rpw')
  280. const type = taskReviewType.value
  281. if (type === '1') {
  282. batchPdfUrl.value = row.pdfUrl
  283. } else if (row['hc_batchPdfUrl']) {
  284. batchPdfUrl.value = row['hc_batchPdfUrl']
  285. } else {
  286. queryTaskInfo(row)
  287. }
  288. pdfDataClick(row, row.id)
  289. }
  290. //默认点击
  291. //获取PDF数据
  292. const queryTaskInfo = async (row, taskids) => {
  293. taskId.value = taskids && taskids.length > 0 ? taskids : row['id']
  294. //验收任务类型传2,不能盖章
  295. // if (row.type !== 2) {
  296. if (row.type !== 2) {
  297. isShowDqBtn.value = true
  298. } else {
  299. isShowDqBtn.value = false
  300. }
  301. const { error, code, data } = await tasksApi.queryTaskInfo({
  302. taskIds: taskids && taskids.length > 0 ? taskids : row['id'],
  303. type: row.type,
  304. })
  305. //处理数据
  306. if (!error && code === 200) {
  307. const alldata = getArrValue(data)
  308. let approvalFileList = alldata
  309. if (approvalFileList.length > 0) {
  310. // await queryCurrentUserData()
  311. if (row['type'] !== 2) {
  312. await queryCurrentUserData()
  313. }
  314. pdfDataClick(row, row.id)
  315. pdfItem.value.pdfUrl = approvalFileList[0].pdfUrl
  316. batchPdfUrl.value = approvalFileList[0].pdfUrl
  317. row['pdfUrl'] = approvalFileList[0].pdfUrl
  318. } else {
  319. batchPdfUrl.value = ''
  320. row['pdfUrl'] = ''
  321. window?.$message?.warning('PDF获取异常')
  322. }
  323. } else {
  324. batchPdfUrl.value = ''
  325. row['pdfUrl'] = ''
  326. window?.$message?.warning(data.msg || 'PDF异常')
  327. }
  328. // } else {
  329. // batchPdfUrl.value = ''
  330. // row['pdfUrl'] = ''
  331. // }
  332. }
  333. const finalArr = ref([])
  334. //确认审批
  335. const ConfirmApprovalClick = async () => {
  336. const formData = taskReviewForm.value
  337. let objarr = []
  338. if (taskReviewType.value === '1') {
  339. //单个废除任务
  340. console.log(111111)
  341. console.log(checkedRowsRef.value, ' checkedRowsRef.value')
  342. objarr.push({
  343. taskId: taskReviewInfo.value.id,
  344. comment: formData.comment,
  345. flag: formData.flag,
  346. sealStrategy: signArr.value,
  347. })
  348. console.log(objarr, 'objarr')
  349. finalArr.value = objarr
  350. } else if (taskReviewType.value === '2') {
  351. //上报任务
  352. if (formData.flag === 'NO' && !formData.comment) {
  353. window?.$message?.warning('请先输入审核意见')
  354. } else {
  355. formData.taskId = taskId.value
  356. console.log(checkedRowsRef.value, 'checkedRowsRef.value')
  357. checkedRowsRef.value.forEach((ele) => {
  358. objarr.push({
  359. taskId: ele.id,
  360. comment: formData.comment,
  361. flag: formData.flag,
  362. sealStrategy: ele.hcSignImageArr,
  363. })
  364. })
  365. console.log(objarr, 'objarr')
  366. finalArr.value = objarr
  367. }
  368. }
  369. SMSAuthLoading.value = true
  370. // const { error, code, msg, data } = await tasksApi.batchApproval({}, false)
  371. //判断数据
  372. SMSAuthLoading.value = false
  373. const ShowAuth = isCheckSmsCodeTime()
  374. SMSAuthShow.value = ShowAuth
  375. //免短信验证
  376. if (!ShowAuth) {
  377. SMSAuthConfirm()
  378. }
  379. }
  380. //短信验证有效期
  381. const smsCodeTime = ref('')
  382. const checkSmsCode = async () => {
  383. const { error, code, data } = await tasksApi.checkSmsCode()
  384. //处理数据
  385. if (!error && code === 200) {
  386. smsCodeTime.value = isString(data) ? data : ''
  387. } else {
  388. smsCodeTime.value = ''
  389. }
  390. }
  391. //验证短信有效期
  392. const isCheckSmsCodeTime = () => {
  393. const smsTime = smsCodeTime.value
  394. if (!smsTime) {
  395. return true
  396. } else {
  397. const toDayTime = dayjs(new Date()).format('YYYY-MM-DD HH:mm:ss')
  398. return dayjs(smsTime).isBefore(toDayTime)
  399. }
  400. }
  401. //短信验证
  402. const SMSAuthLoading = ref(false)
  403. const SMSAuthShow = ref(false)
  404. const SMSAuthConfirm = () => {
  405. const type = taskReviewType.value
  406. if (type === '1') {
  407. saveCompleteApprovalTask()
  408. } else {
  409. batchCompleteApprovalTask()
  410. }
  411. checkSmsCode()
  412. }
  413. const SMSAuthCancel = () => {
  414. SMSAuthShow.value = false
  415. }
  416. //单个审批
  417. const saveCompleteApprovalTask = async () => {
  418. SMSAuthLoading.value = true
  419. const { error, code, msg, data } = await tasksApi.batchApproval({
  420. taskArchiveDtoList: finalArr.value,
  421. projectId: projectId.value,
  422. contractId: contractId.value,
  423. }, false)
  424. //处理数据
  425. SMSAuthLoading.value = false
  426. if (!error && code === 200) {
  427. SMSAuthShow.value = false
  428. showTaskReviewModal.value = false
  429. window?.$message?.success('审批成功')
  430. setTimeout(() => {
  431. window?.location?.reload() //刷新页面
  432. }, 3000)
  433. } else if (code === 400) {
  434. window?.$message?.error(msg)
  435. } else {
  436. window?.$message?.warning('审批异常')
  437. }
  438. }
  439. //批量审批
  440. const batchCompleteApprovalTask = async () => {
  441. SMSAuthLoading.value = true
  442. const { error, code, msg, data } = await tasksApi.batchApproval({
  443. taskArchiveDtoList: finalArr.value,
  444. projectId: projectId.value,
  445. contractId: contractId.value,
  446. }, false)
  447. //处理数据
  448. SMSAuthLoading.value = false
  449. if (!error && code === 200) {
  450. SMSAuthShow.value = false
  451. showTaskReviewModal.value = false
  452. window?.$message?.success('审批成功')
  453. setTimeout(() => {
  454. window?.location?.reload() //刷新页面
  455. }, 3000)
  456. } else if (code === 400) {
  457. window?.$message?.error(msg)
  458. } else {
  459. window?.$message?.warning('审批出错')
  460. }
  461. }
  462. //设置重签规则
  463. const showSetSignRulesModal = ref(false)
  464. const setPactVal = ref(true)
  465. const formReport = ref({ date: 1, active: true })
  466. const setSignRulesClick = () => {
  467. showSetSignRulesModal.value = true
  468. }
  469. const dateUpdateValue = (val) => {
  470. formReport.value.date = val
  471. }
  472. </script>
  473. <style lang="scss" scoped>
  474. @import '../../styles/tasks/hc-data.scss';
  475. </style>