123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389 |
- <template>
- <hc-sys id="app-sys" class="h-100vh hc-task-page" :isNavBar="false">
- <view id="hc-task-nav-bar" class="hc-task-nav-bar">
- <view class="task-nav-bar">
- <view class="segmented-bar">
- <template v-for="item in taskTypeData">
- <view class="task-tab-item"
- :class="item.key === taskType?'task-cur':''"
- @click="taskTypeChange(item)"
- >{{item.name}}</view>
- </template>
- </view>
- <view class="more-bar" v-if="taskType === 1 && taskList.length > 0" @click="moreBarClick">
- <text class="i-ri-more-2-fill icon"/>
- </view>
- </view>
- <view class="controls-bar-box">
- <view class="controls-bar">
- <view class="left">
- <text class="i-ri-filter-fill icon" :class="isControlsFilter?'cur':''" @click="dateFilterClick"/>
- <text class="i-ri-filter-off-fill icon" @click="dateFilterClear"/>
- </view>
- <view class="right">
- <text class="i-ri-sort-desc icon" :class="searchForm.ordType === 1?'cur':''" @click="changeOrdType(1)"/>
- <text class="i-ri-sort-asc icon" :class="searchForm.ordType === 2?'cur':''" @click="changeOrdType(2)"/>
- </view>
- </view>
- <view class="controls-filter" v-if="isControlsFilter">
- <view class="search-form-date">
- <picker class="search-date-input" mode="date" :value="searchForm.startTimeValue" @change="startDateChange">
- <view class="content">
- <view class="text">{{searchForm.startTimeValue??'点此选择开始日期'}}</view>
- <text class="i-ri-close-circle-line icon" v-if="searchForm.startTimeValue" @click.stop="startDateClear"/>
- </view>
- </picker>
- </view>
- <view class="search-form-date">
- <picker class="search-date-input" mode="date" :value="searchForm.endTimeValue" @change="endDateChange">
- <view class="content">
- <view class="text">{{searchForm.endTimeValue??'点此选择结束日期'}}</view>
- <text class="i-ri-close-circle-line icon" v-if="searchForm.endTimeValue" @click.stop="endDateClear"/>
- </view>
- </picker>
- </view>
- <button class="search-form-btn" type="primary" size="mini" @click="searchClick">查询</button>
- </view>
- </view>
- </view>
- <!--下拉刷新区域-->
- <z-paging ref="pageRef" :style="pagingStyle" v-model="taskList" @query="getTaskList">
- <uni-card v-for="item in taskList" padding="0" :class="item.check?'is-check':''" @click="taskItemClick(item)">
- <view class="py-3 text-30 text-black">{{item.taskName}}</view>
- <view slot="actions" class="card-actions no-border">
- <view class="card-actions-item">
- <view class="item-icon-check" v-if="showCheck">
- <uni-icons type="checkbox-filled" size="26" color="#ee5b20" v-if="item.check"/>
- <uni-icons type="checkbox" size="26" color="#9a9a9a" v-else/>
- </view>
- <text>{{item.startTime}}提交的申请</text>
- </view>
- <view class="card-actions-item" v-if="taskType === 1">
- <uni-icons type="calendar" size="18" color="#EE5B20"/>
- <text class="card-actions-item-text" style="color: #EE5B20;">审批</text>
- </view>
- <view class="card-actions-item" v-else>
- <text class="card-actions-item-text">{{item.taskStatusName}}</text>
- </view>
- </view>
- </uni-card>
- </z-paging>
- <!--底部操作区域 -->
- <view id="hc-bottom-bar" class="hc-bottom-bar"/>
- <view id="hc-bottom-btn-bar" class="hc-bottom-btn-bar">
- <view class="show-check-tabbars" v-if="showCheck">
- <view class="check-bar">
- <view class="check-box" @click="allCheckClick">
- <text class="text">全选</text>
- <uni-icons type="checkbox-filled" size="26" color="#ee5b20" v-if="isAllCheck"/>
- <uni-icons type="checkbox" size="26" color="#9a9a9a" v-else/>
- </view>
- <view class="text-box">
- <text class="text">共勾选</text>
- <text class="text" style="color: #ee5b20;">{{itemCheckIndex}}</text>
- <text class="text">条任务</text>
- </view>
- </view>
- <view class="btn-bar">
- <button class="check-btn" size="mini" @click="batchApproval">批量审批</button>
- <button class="check-btn" size="mini" @click="cancelTaskClick">批量废除</button>
- <button class="check-btn cancel" size="mini" @click="cancelCheckClick">取消操作</button>
- </view>
- </view>
- </view>
- </hc-sys>
- </template>
- <script setup>
- import {getCurrentInstance, ref} from "vue";
- import mainApi from '~api/tasks/data';
- import {onShow, onReady} from '@dcloudio/uni-app'
- import {errorToast, querySelect, successToast} from "@/utils/tools";
- import {arrToKey, getArrValue, getObjValue} from "js-fast-way";
- import {useAppStore} from "@/store";
- //初始变量
- const store = useAppStore()
- const projectId = ref(store.projectId);
- const contractId = ref(store.contractId);
- const instance = getCurrentInstance().proxy
- const isNodes = ref(false)
- const pageRef = ref(null)
- onReady(() => {
- setPagingStyle()
- isNodes.value = true
- })
- onShow(() => {
- projectId.value = store.projectId
- contractId.value = store.contractId
- if (isNodes.value) {
- searchClick()
- }
- })
- //内容区域
- const pagingStyle = ref({
- position: 'relative',
- width: '100%',
- bottom: 0,
- })
- const setPagingStyle = async () => {
- const {height: appHeight} = await querySelect(instance, 'app-sys')
- const {height: navHeight} = await querySelect(instance, 'hc-task-nav-bar')
- const {height: bottomHeight} = await querySelect(instance, 'hc-bottom-bar')
- const {height: bottomBtnHeight} = await querySelect(instance, 'hc-bottom-btn-bar')
- // #ifdef H5
- let content = navHeight + bottomHeight + bottomBtnHeight
- pagingStyle.value.height = (appHeight - content) + 'px'
- // #endif
- // #ifdef APP-PLUS
- const {screenHeight, safeArea} = uni.getWindowInfo()
- content = navHeight + (screenHeight - safeArea.bottom) + bottomBtnHeight
- pagingStyle.value.height = (screenHeight - content) + 'px'
- // #endif
- }
- //顶部类型切换
- const taskType = ref(1)
- const taskTypeData = [
- {key: 1, name: '我的审批'},
- {key: 2, name: '已办结的'},
- {key: 3, name: '我发起的'}
- ]
- const taskTypeChange = ({key}) => {
- taskType.value = key
- searchClick()
- }
- //批量操作
- const showCheck = ref(false)
- const moreBarClick = () => {
- showCheck.value = !showCheck.value
- setPagingStyle()
- }
- //日期选择器弹出框
- const isControlsFilter = ref(false)
- const dateFilterClick = () => {
- isControlsFilter.value = !isControlsFilter.value
- setPagingStyle()
- }
- const dateFilterClear = () => {
- isControlsFilter.value = false
- searchForm.value.startTimeValue = null
- searchForm.value.endTimeValue = null
- setPagingStyle()
- searchClick()
- }
- //开启日期选择完毕
- const startDateChange = (e) => {
- const val = e.detail.value, endTime = searchForm.value.endTimeValue
- if (endTime && val && val > endTime) {
- errorToast('开始日期不能大于结束日期', 2000)
- return false
- } else {
- searchForm.value.startTimeValue = val
- }
- }
- const startDateClear = () => {
- searchForm.value.startTimeValue = null
- }
- //结束日期选择完毕
- const endDateChange = (e) => {
- const val = e.detail.value, startTime = searchForm.value.startTimeValue
- if (startTime && val && val < startTime) {
- errorToast('结束日期不能小于开始日期', 2000)
- return false
- } else {
- searchForm.value.endTimeValue = val
- }
- }
- const endDateClear = () => {
- searchForm.value.endTimeValue = null
- }
- //条件搜索
- const searchClick = () => {
- pageRef.value?.reload()
- }
- //排序切换
- const changeOrdType = (type) => {
- searchForm.value.ordType = type
- searchClick()
- }
- //搜索表单
- const searchForm = ref({
- startTimeValue: null, endTimeValue: null, ordType: 1
- })
- //获取任务列表数据
- const taskList = ref([])
- const getTaskList = async (pageNo, pageSize) => {
- uni.showLoading({title: '获取数据中...', mask: true});
- const { data } = await mainApi.queryTaskPageList({
- ...searchForm.value,
- projectIdValue: projectId.value,
- currentContractId: contractId.value,
- contractIdValue: contractId.value,
- selectedType: taskType.value,
- batchValue: '',
- queryValue: '',
- statusValue: '',
- typeValue: '',
- current: pageNo,
- size: pageSize,
- })
- const res = getObjValue(data)
- uni.hideLoading();
- isNodes.value = true
- pageRef.value?.complete(getArrValue(res?.records));
- if (isAllCheck.value) {
- isAllCheck.value = itemCheckIndex.value === taskList.value.length
- }
- }
- //任务被点击
- const itemCheckIndex = ref(0)
- const taskItemClick = (item) => {
- if (showCheck.value) {
- const check = !item.check, list = taskList.value
- if (check) {
- itemCheckIndex.value++
- } else {
- itemCheckIndex.value--
- }
- item.check = check
- isAllCheck.value = list.length === itemCheckIndex.value
- } else {
- toTaskDetail([item])
- }
- }
- //全选
- const isAllCheck = ref(false)
- const allCheckClick = () => {
- uni.showLoading({title: '处理中...', mask: true});
- const list = taskList.value, isCheck = !isAllCheck.value
- for (let i = 0; i < list.length; i++) {
- list[i].check = isCheck;
- }
- itemCheckIndex.value = isCheck ? list.length : 0
- isAllCheck.value = isCheck
- uni.hideLoading();
- }
- //取消操作
- const cancelCheckClick = () => {
- const list = taskList.value
- for (let i = 0; i < list.length; i++) {
- list[i].check = false;
- }
- itemCheckIndex.value = 0
- showCheck.value = false
- setPagingStyle()
- }
- //批量审批
- const batchApproval = () => {
- let rows = taskList.value.filter((item) => {
- return item.check
- })
- if (rows.length <= 0) {
- errorToast('请选择需要审批的任务')
- return false
- }
- //路由跳转
- toTaskDetail(rows)
- }
- //跳转任务详情
- const toTaskDetail = (rows) => {
- const node = encodeURIComponent(JSON.stringify({
- rows: rows,
- isTask: taskType.value === 1
- }))
- uni.navigateTo({
- url: '/pages/task/detail?node=' + node,
- events: {
- finish: () => {
- searchClick();
- }
- }
- });
- }
- //批量废除
- const popupRef = ref(null)
- const argument = ref('')
- const cancelTaskList = ref([])
- const cancelTaskClick = () => {
- cancelTaskList.value = []
- let rows = taskList.value.filter((item) => {
- return item.check
- })
- if (rows.length <= 0) {
- errorToast('请选择需要废除的任务')
- return false
- }
- cancelTaskList.value = rows
- argument.value = ''
- popupRef.value?.open()
- }
- //确认废除
- const confirmRepeal = () => {
- if (!argument.value) {
- errorToast('请先填写废除理由')
- return false
- }
- batchCompleteApprovalTaskApi(cancelTaskList.value)
- }
- //批量废除接口
- const batchCompleteApprovalTaskApi = async (rows) => {
- uni.showLoading({title: '批量废除中...', mask: true});
- let taskIds = arrToKey(rows, 'taskId', ',')
- let approvalType = arrToKey(rows, 'approvalType', ',')
- let formDataId = arrToKey(rows, 'formDataId', ',')
- let parallelProcessInstanceIds = arrToKey(rows, 'parallelProcessInstanceId', ',')
- const {error, code, msg} = await mainApi.batchCompleteApprovalTask({
- flag: 'NO',
- comment: argument.value,
- taskIds: taskIds,
- approvalType: approvalType,
- formDataId: formDataId,
- parallelProcessInstanceIds: parallelProcessInstanceIds,
- })
- uni.hideLoading();
- if (!error && code === 200) {
- successToast('废除成功')
- cancelClick()
- searchClick()
- } else {
- errorToast(`废除失败:${msg}`)
- }
- }
- //取消废除
- const cancelClick = () => {
- popupRef.value?.close()
- argument.value = ''
- }
- </script>
- <style lang="scss" scoped>
- page {
- background: #EFEFF4;
- height: 100%;
- }
- </style>
- <style lang="scss">
- @import "@/style/task/index.scss";
- </style>
|