123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454 |
- <template>
- <hc-sys class="h-full hc-app-task-detail" :isNavBar="false">
- <uni-section class="mt-0.5" title="当前任务名称" type="line">
- <template v-slot:right>
- <view class="hc-flex text-gray-5" @click="taskPopupClick">
- <text class="mr-1">切换任务</text>
- <uni-icons type="bottom" size="18" color="#6b7280"/>
- </view>
- </template>
- <view class="task-name">{{taskInfo.taskName}}</view>
- <view class="task-report-info">
- <view>上报人:{{taskInfo.taskReportUserName}}</view>
- <view>{{taskInfo.startTime}}</view>
- </view>
- </uni-section>
- <uni-section class="mt-2" :title="`当前表格 (共${taskFileInfo?.fileNum ?? 0}张)`" sub-title="点击表格名称查看PDF" type="line">
- <template v-slot:right>
- <view class="hc-flex text-gray-5" @click="tablePopupClick">
- <text class="mr-1">切换表格</text>
- <uni-icons type="bottom" size="18" color="#6b7280"/>
- </view>
- </template>
- <view class="task-file-name" @click="viewPdfClick">{{taskFileInfo.fileName}}</view>
- </uni-section>
- <!--底部操作栏-->
- <hc-tabbars v-if="isTaskAuth">
- <button type="primary" class="action-bar-btn" @click="approveClick">
- <text>审</text> <text class="ml-6">批</text>
- </button>
- </hc-tabbars>
- <!-- 普通弹窗 -->
- <uni-popup ref="popupRef" class="hc-popup" type="bottom">
- <view class="task-popup-content">
- <template v-if="popupType === 1">
- <view class="title">请选择审批是否通过?</view>
- <view class="popup-btn-bar">
- <button type="primary" class="popup-btn c1" @click="agreeClick">同意签字审批</button>
- </view>
- <view class="popup-btn-bar">
- <button type="primary" class="popup-btn c2" @click="cancelTaskClick">废除任务</button>
- </view>
- <view class="popup-btn-bar">
- <button type="primary" class="popup-btn c3" @click="cancelApproval">取消审批</button>
- </view>
- </template>
- <template v-if="popupType === 2">
- <view class="title">请输入验证码验证是否为本人操作授权</view>
- <view class="popup-code-bar">
- <view class="btn-tel-code-bar">
- <view class="btn-tel">{{userInfo.phone}}</view>
- <view class="btn-code">
- <button type="primary" :disabled="isCodeDisabled" class="popup-btn code" size="mini" @click="getCodeClick">
- {{ isCodeDisabled ? `倒计时${currentCodeTime}s` : '发送验证码' }}
- </button>
- </view>
- </view>
- <view class="code-input-bar">
- <input class="code-input" v-model="smsCode" placeholder="请输入验证码"/>
- </view>
- </view>
- <view class="popup-btn-bar">
- <button type="primary" class="popup-btn c4" @click="confirmApproval">确认审批</button>
- </view>
- <view class="popup-btn-bar">
- <button type="primary" class="popup-btn c3" @click="cancelClick">取消操作</button>
- </view>
- </template>
- <template v-if="popupType === 3">
- <view class="popup-argument-bar">
- <textarea class="argument-input" v-model="argument" :maxlength="-1" placeholder="请输入废除任务的理由"/>
- </view>
- <view class="popup-btn-bar">
- <button type="primary" class="popup-btn c1" @click="confirmRepeal">确认废除</button>
- </view>
- <view class="popup-btn-bar">
- <button type="primary" class="popup-btn c3" @click="cancelClick">取消操作</button>
- </view>
- </template>
- </view>
- </uni-popup>
- <!-- 任务列表 -->
- <uni-popup ref="popupTaskRef" type="bottom">
- <view class="relative bg-white h-50vh hc-p br-t">
- <view class="text-black mb-3 text-center">选择任务数据</view>
- <view class="relative hc-app-task-view">
- <template v-for="(item, index) in taskList" :key="index">
- <view class="relative mt-3" :class="item.id === taskInfo.id ? 'text-blue' :''" @click="taskClick(item)">{{item.taskName}}</view>
- </template>
- </view>
- </view>
- </uni-popup>
- <!-- 表格列表 -->
- <uni-popup ref="popupTableRef" type="bottom">
- <view class="relative bg-white h-50vh hc-p br-t">
- <view class="text-black mb-3 text-center">选择表格数据</view>
- <template v-for="(item, index) in taskInfo.approvalFileList" :key="index">
- <view class="relative mt-3" :class="item.id === taskFileInfo.id ? 'text-blue' :''" @click="taskFileClick(item)">{{item.fileName}}</view>
- </template>
- </view>
- </uni-popup>
- </hc-sys>
- </template>
- <script setup>
- import {ref, nextTick, getCurrentInstance} from "vue";
- import {onLoad, onReady} from '@dcloudio/uni-app'
- import {arrToKey, getArrValue, getObjValue, isString} from "js-fast-way";
- import {errorToast, successToast, toPdfPreview} from "@/utils/tools";
- import {checkFlowUserIsExistPfxFile, saveSmsTimeout, sendNotice} from "~api/other/index";
- import mainApi from '~api/tasks/data';
- import {useAppStore} from "@/store";
- import dayjs from "dayjs";
- //初始变量
- const store = useAppStore()
- const instance = getCurrentInstance().proxy
- const projectId = ref(store.projectId);
- const contractId = ref(store.contractId);
- const userInfo = ref(store.userInfo);
- const taskList = ref([])
- const taskInfo = ref({})
- const isTaskAuth = ref(false)
- //页面传参数据
- let eventChannel = null;
- const getEventChannel = async () => {
- await nextTick();
- eventChannel = instance.getOpenerEventChannel();
- }
- onLoad(({node}) => {
- const {rows, isTask} = node ? JSON.parse(decodeURIComponent(node)) : {};
- const res = getArrValue(rows);
- if (res.length > 0) {
- taskInfo.value = res[0]
- }
- taskList.value = res
- isTaskAuth.value = !!isTask
- getDataApi()
- })
- //渲染完成
- onReady(() => {
- uni.setNavigationBarTitle({title: '审批任务'})
- })
- //获取数据
- const getDataApi = async () => {
- uni.showLoading({title: '获取数据中...', mask: true});
- await getEventChannel()
- await getTaskInfo()
- checkSmsCode().then()
- uni.hideLoading();
- }
- //切换任务
- const taskClick = (item) => {
- taskInfo.value = item
- taskFileInfo.value = item.approvalFileList[0]
- popupTaskRef.value?.close()
- }
- //切换PDF
- const taskFileInfo = ref({})
- const taskFileClick = (item) => {
- taskFileInfo.value = item
- popupTableRef.value?.close()
- }
- //获取任务详情
- const getTaskInfo = async () => {
- const rows = taskList.value
- if (rows.length <= 0) return false
- //处理详情数据
- for (let i = 0; i < rows.length; i++) {
- const res = await queryApprovalParameter(rows[i])
- rows[i].approvalFileList = res.approvalFileList
- }
- taskInfo.value = getObjValue(rows[0])
- taskFileInfo.value = getObjValue(rows[0].approvalFileList[0])
- taskList.value = rows
- }
- //获取审批详情
- const queryApprovalParameter = async ({parallelProcessInstanceId, formDataId, approvalType}) => {
- const { data } = await mainApi.queryApprovalParameter({
- projectId: projectId.value,
- contractId: contractId.value,
- parallelProcessInstanceId: parallelProcessInstanceId ?? '',
- formDataId: formDataId ?? '',
- approvalType: approvalType ?? ''
- })
- const res = getObjValue(data)
- const list = getArrValue(res.approvalFileList)
- for (let i = 0; i < list.length; i++) {
- list[i].fileNum = await queryPDFnumApi(list[i]?.fileUrl)
- }
- res.approvalFileList = list
- return getObjValue(data)
- }
- //查询PDF数量
- const queryPDFnumApi = async (pdfUrl) => {
- const { data } = await mainApi.queryPDFnum({
- projectId: projectId.value,
- contractId: contractId.value,
- url: pdfUrl
- })
- return data ? data : 0
- }
- //任务列表
- const popupTaskRef = ref(null)
- const taskPopupClick = () => {
- popupTaskRef.value?.open()
- }
- //表格列表
- const popupTableRef = ref(null)
- const tablePopupClick = () => {
- popupTableRef.value?.open()
- }
- //审批弹窗
- const popupRef = ref(null)
- const popupType = ref(1)
- const approveClick = () => {
- popupType.value = 1
- popupRef.value?.open()
- }
- //短信验证有效期
- const smsCodeTime = ref('')
- const checkSmsCode = async () => {
- const {data} = await mainApi.checkSmsCode()
- smsCodeTime.value = isString(data) ? data : '';
- }
- //验证短信有效期
- const isCheckSmsCodeTime = () => {
- const smsTime = smsCodeTime.value;
- if (!smsTime) return true
- const toDayTime = dayjs().format('YYYY-MM-DD HH:mm:ss')
- return dayjs(smsTime).isBefore(toDayTime)
- }
- //同意审批短信验证
- const smsCode = ref('')
- const agreeClick = async () => {
- const showAuth = isCheckSmsCodeTime()
- if (showAuth) {
- smsCode.value = ''
- popupType.value = 2
- } else {
- const {error, code, msg, data} = await checkFlowUserIsExistPfxFile({
- projectId: projectId.value,
- contractId: contractId.value,
- })
- if (!error && code === 200 && data === true) {
- const showAuth = isCheckSmsCodeTime()
- if (showAuth) {
- smsCode.value = ''
- popupType.value = 2
- } else {
- batchTaskApproval('ok').then()
- }
- } else {
- errorToast(msg)
- cancelApproval()
- }
- }
- }
- //验证码倒计时
- const totalTime = 60 //总时间,单位秒
- const isCodeDisabled = ref(false) //是否开启倒计时
- const recordingCodeTime = ref(0) //记录时间变量
- const currentCodeTime = ref(0) //显示时间变量
- //获取短信验证码
- const resCode = ref('')
- const getCodeClick = async () => {
- const {phone} = userInfo.value
- if (!phone) {
- errorToast('您的手机号是空的,无法获取验证码')
- return false
- }
- const { error, code, msg } = await sendNotice({
- phone: phone
- })
- //处理数据
- if (!error && code === 200 && msg) {
- resCode.value = msg
- //把显示时间设为总时间
- currentCodeTime.value = totalTime
- //开始倒计时
- isCodeDisabled.value = true
- //执行倒计时
- checkingTime()
- successToast('发送成功')
- } else {
- resCode.value = ''
- errorToast(msg)
- }
- }
- //倒计时
- const checkingTime = () => {
- //判断是否开启
- if (isCodeDisabled.value) {
- //判断显示时间是否已到0,判断记录时间是否已到总时间
- if (currentCodeTime.value > 0 && recordingCodeTime.value <= totalTime) {
- //记录时间增加 1
- recordingCodeTime.value++
- //显示时间,用总时间 - 记录时间
- currentCodeTime.value = totalTime - recordingCodeTime.value
- //1秒钟后,再次执行本方法
- setTimeout(() => {
- checkingTime()
- }, 1000)
- } else {
- //时间已完成,还原相关变量
- isCodeDisabled.value = false //关闭倒计时
- recordingCodeTime.value = 0 //记录时间为0
- currentCodeTime.value = totalTime //显示时间为总时间
- }
- } else {
- //倒计时未开启,初始化默认变量
- isCodeDisabled.value = false
- recordingCodeTime.value = 0
- currentCodeTime.value = totalTime
- }
- }
- //确认审批
- const confirmApproval = () => {
- if (!resCode.value) {
- errorToast('请先获取验证码')
- return false
- } else if (!smsCode.value) {
- errorToast('请先输入验证码')
- return false
- } else if (resCode.value !== smsCode.value) {
- errorToast('验证码错误')
- return false
- }
- //验证码过期时间
- saveSmsTimeout({code: resCode.value})
- //处理数据
- batchTaskApproval('ok')
- checkSmsCode()
- }
- //批量审批
- const batchTaskApproval = async (type) => {
- let res = {}, t = type === 'ok' ? '审批' : '废除';
- uni.showLoading({title: '提交审批中...', mask: true});
- if (type === 'ok') {
- res = await batchCompleteApprovalTaskApi({
- flag: 'OK',
- comment: 'OK',
- })
- } else {
- res = await batchCompleteApprovalTaskApi({
- flag: 'NO',
- comment: argument.value,
- })
- }
- //处理数据
- uni.hideLoading();
- const {error, code, msg} = res
- if (!error && code === 200) {
- successToast(`${t}成功`)
- cancelApproval()
- eventChannel.emit('finish');
- setTimeout(() => {
- uni.navigateBack()
- }, 3000)
- } else {
- errorToast(`${t}失败:${msg}`)
- }
- }
- //批量审批
- const batchCompleteApprovalTaskApi = async (obj = {}) => {
- const rows = taskList.value
- let taskIds = arrToKey(rows, 'taskId', ',')
- let approvalType = arrToKey(rows, 'approvalType', ',')
- let formDataId = arrToKey(rows, 'formDataId', ',')
- let parallelProcessInstanceIds = arrToKey(rows, 'parallelProcessInstanceId', ',')
- return await mainApi.batchCompleteApprovalTask({
- ...obj,
- projectId: projectId.value,
- contractId: contractId.value,
- taskIds,
- approvalType,
- formDataId,
- parallelProcessInstanceIds
- })
- }
- //废除任务并输入理由
- const argument = ref('')
- const cancelTaskClick = () => {
- argument.value = ''
- popupType.value = 3
- }
- //确认废除
- const confirmRepeal = () => {
- if (!argument.value) {
- errorToast('请先填写废除理由')
- return false
- }
- batchTaskApproval('no')
- }
- //取消审批
- const cancelApproval = () => {
- popupType.value = 1
- popupRef.value?.close()
- }
- //取消操作
- const cancelClick = () => {
- popupType.value = 1
- smsCode.value = ''
- argument.value = ''
- }
- //查看PDF
- const viewPdfClick = () => {
- const {fileUrl} = taskFileInfo.value
- if (fileUrl) {
- // #ifdef H5
- window.open(fileUrl, '_blank')
- // #endif
- // #ifdef APP-PLUS
- uni.navigateTo({
- url: '/pages/index/preview?url=' + encodeURIComponent(fileUrl)
- });
- // #endif
- } else {
- errorToast('PDF文件不存在')
- }
- }
- </script>
- <style lang="scss">
- @import "@/style/task/detail.scss";
- </style>
|