You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ocr-web/src/views/final/comp/RepeatTaskTableModal.vue

602 lines
12 KiB

<script lang="ts" setup>
import {
computed,
defineEmits,
h,
nextTick,
onBeforeMount,
onMounted,
onUnmounted,
reactive,
ref,
unref,
watch,
} from 'vue'
import { NDataTable, useDialog, useMessage } from 'naive-ui'
import type { DataTableColumns, DataTableRowKey } from 'naive-ui'
import { useRouter } from 'vue-router'
import {
ListAction,
StatusItem,
} from '../comp'
import { RejectModal } from './index'
import { useDictionary } from '@/store/modules/dictonary'
import type { RowData } from '@/config/final'
import { getRepeatList } from '@/api/final'
import { formatToDateHMS } from '@/utils/dateUtil'
import { audit } from '@/api/task/task'
import NotPassed from '@/components/Approval/NotPassed.vue'
const emit = defineEmits<{
(e: 'commit', columns: any[])
}>()
const dicStore = useDictionary()
const message = useMessage()
const show = ref(false)
const izstatusList = ref([])
const dialog = useDialog()
const checkedRowKeys = ref([])
const router = useRouter()
onBeforeMount(() => {
dicStore.fetchizstatusListt()
})
function closeModal() {
show.value = false
}
async function handleSumbit(e: MouseEvent) {
e.preventDefault()
closeModal()
}
const columns: DataTableColumns<RowData> = [
{
type: 'selection',
fixed: 'left',
width: 50,
disabled(row: any) {
return row.states !== 2
},
},
{
title: '任务ID',
key: 'id',
fixed: 'left',
width: 200,
ellipsis: {
tooltip: true,
},
render(row: any) {
return row.fromtaskid
},
},
{
title: '任务名称',
key: 'fromtaskname',
fixed: 'left',
width: 150,
ellipsis: {
tooltip: true,
},
},
{
title: '审批节点',
key: 'approvalnode',
width: 100,
},
{
title: '审批状态',
key: 'states',
width: 120,
render(row) {
const item: any = izstatusList.value.find(
(item: any) => item.value == row.states,
)
return h(StatusItem, {
id: row.id,
status: row.states,
label: item ? item.label : '',
})
},
},
{
title: '图片相似度',
key: 'similarityscore',
width: 100,
render(row: any) {
return h('div', {
id: row.id,
style: { color: row.similarityscore === 100 ? '#FF4E4F' : '' },
}, { default: () => row.similarityscore ? `${row.similarityscore}%` : '' })
},
},
{
title: '提报时间',
key: 'fromuptime',
width: 200,
render(row: any) {
return formatToDateHMS(row.createdate || 0)
},
},
{
title: '更新时间',
key: 'updatetime',
width: 200,
},
{
title: '操作',
key: 'actions',
width: 200,
fixed: 'right',
render(row) {
return h(ListAction, {
id: row.id,
status: row.states,
trigger: (action) => {
actionHandler(action, row)
},
})
},
},
]
const notPassModalRef = ref(null) // 不通过弹窗
const rejectModalRef = ref(null)
const columnsRef = ref(columns)
const tableRef = ref<InstanceType<typeof NDataTable>>()
const rowKey = (row: RowData) => row.id
const loading = ref(true)
const total = ref(0)
const pagination = reactive({
page: 1,
pageCount: 1,
pageSize: 10,
showSizePicker: true,
pageSizes: [
{
label: '10 每页',
value: 10,
},
{
label: '15 每页',
value: 15,
},
{
label: '30 每页',
value: 30,
},
{
label: '50 每页',
value: 50,
},
],
showQuickJumper: true,
prefix: () => `${total.value} 条数据`,
})
const tableData = ref<Array<RowData>>([])
const selectionIds = ref<DataTableRowKey[]>([])
const deviceHeight = ref(500)
const maxHeight = computed(() => {
return tableData.value.length ? `${unref(deviceHeight)}px` : 'auto'
})
async function query(page: number, pageSize: number) {
const result = await getRepeatList({
sortorder: 'asc',
pageSize: pagination.pageSize,
pageNo: pagination.page,
sortname: '',
})
console.log(666666)
console.log(result)
const { data, pageCount, totalCount } = result
total.value = totalCount
tableData.value = data
pagination.page = page
pagination.pageCount = pageCount
loading.value = false
}
watch(
() => dicStore.izstatusList,
(newval) => {
izstatusList.value = newval
},
)
async function handlePageChange(currentPage) {
if (loading.value)
return
pagination.page = currentPage
const { pageSize } = pagination
await query(currentPage, pageSize)
}
async function handlePageSizeChange(currentPageSize) {
if (loading.value)
return
const { page } = pagination
pagination.pageSize = currentPageSize
await query(page, currentPageSize)
}
function handleCheck(rowKeys: DataTableRowKey[]) {
selectionIds.value = rowKeys
}
function validate(items: any[]) {
if (items.length === 0)
return '至少选中一个任务'
return null
}
function actionHandler(action: any, row: any) {
const { key } = action
switch (key) {
case 'view':
goDetail(row)
break
case 'reset':
// resetHandler()
break
case 'approval':
singleApproval(row)
break
case 'reject':
rejectHandler([row])
break
default:
break
}
}
function getSelectItems() {
return tableData.value.filter(item => selectionIds.value.includes(item.id))
}
// 单个审批通过
function singleApproval(row) {
const param = {
result: true,
comment: '',
disposeType: '',
disposeTypeId: '',
failCauseId: '',
failCauseName: '',
flowTaskInfoList: [
{
formId: row.id,
taskId: row.taskId,
taskName: row.fromTaskName,
},
],
}
doAudit(param)
}
// 批量通过
function batchApproval() {
const items: any = getSelectItems()
const msg = validate(items)
if (msg !== null) {
message.error(msg)
return
}
console.log(items)
const list: any = []
items.forEach((item) => {
list.push({
formId: item.id,
taskId: item.taskId,
taskName: item.fromtaskname,
})
})
const param = {
result: true,
comment: '',
disposeType: '',
disposeTypeId: '',
failCauseId: '',
failCauseName: '',
flowTaskInfoList: list,
}
doAudit(param)
}
// 批量不通过
function batchReject() {
const items: any = getSelectItems()
rejectHandler(items)
}
// 审核通过
function doAudit(param: any) {
dialog.info({
title: '确认提示',
content: '确认给该任务审批为【通过】吗?',
positiveText: '确定',
negativeText: '取消',
onPositiveClick: () => {
audit(param).then((res) => {
const { code } = res
if (code === 'OK') {
message.success(res.message)
reload()
}
else { message.error(res.message) }
})
},
onNegativeClick: () => {},
})
}
// 审核不通过
function rejectHandler(list) {
const msg = validate(list)
if (msg !== null) {
message.error(msg)
return
}
const modal = unref(notPassModalRef)! as any
modal.showModal(list)
}
// query(pagination.page, pagination.pageSize)
function showModal() {
query(pagination.page, pagination.pageSize)
show.value = true
}
function reload() {
selectionIds.value = []
checkedRowKeys.value = []
query(pagination.page, pagination.pageSize)
}
function goDetail(row) {
router.push({ name: 'final-detail', query: { id: row.id, packageid: row.packageid, taskindex: row.taskIndex } })
}
const showActions = computed(() => {
return selectionIds.value.length
})
function switchBatch() {
selectionIds.value = []
checkedRowKeys.value = []
}
defineExpose({
showModal,
})
</script>
<template>
<div>
<NotPassed ref="notPassModalRef" @success="reload" />
<n-modal v-model:show="show" transform-origin="center">
<n-card
class="cardstyle"
:bordered="false"
size="huge"
role="dialog"
aria-modal="true"
>
<div class="wrapper">
<div class="card-top">
<span class="wrapper-title">重复任务</span>
<div class="wrapper-bar">
<div class="wrapper-info">
<span>任务信息</span>
</div>
</div>
<div v-show="showActions" class="batch">
<div style="display: flex; align-items: center">
<img class="btn-approval btn-left" style="margin-left: 16px" src="@/assets/images/task/btn-not-pass.png" alt="" @click.stop="batchReject">
<SvgIcon size="24" name="vs" />
<img class="btn-approval" src="@/assets/images/task/btn-pass.png" alt="" @click.stop="batchApproval">
</div>
<div class="batch-right">
<div class="select">
已选中 <span class="num">{{ selectionIds.length }}</span>
</div>
<div class="line" />
<div class="clear" @click="switchBatch">
清空
</div>
</div>
</div>
<div class="wrapper-content">
<NDataTable
ref="tableRef"
v-model:checked-row-keys="checkedRowKeys"
remote
:columns="columnsRef"
:scroll-x="1250"
:max-height="maxHeight"
:data="tableData"
:loading="loading"
:pagination="pagination"
:row-key="rowKey"
@update:page="handlePageChange"
@update-page-size="handlePageSizeChange"
@update:checked-row-keys="handleCheck"
/>
</div>
</div>
</div>
<div class="wrapper-footer">
<n-button class="btn1" type="info" @click="handleSumbit">
确定
</n-button>
<n-button secondary class="btn" style="margin-left: 15px" @click="closeModal">
</n-button>
</div>
</n-card>
</n-modal>
<RejectModal ref="rejectModalRef" @commit="rejectHandler" />
</div>
</template>
<style lang="less" scoped>
.batch {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 27px;
.btn-approval{
width: 68px;
height: 28px;
cursor: pointer;
}
.batch-right {
display: flex;
align-items: center;
.select{
font-size: 14px;
font-family: PingFang SC, PingFang SC-Regular;
font-weight: 500;
text-align: center;
color: #666666;
}
.num{
color: #507AFD;
}
.line{
width: 1px;
height: 14px;
background: #d8d8d8;
margin: 0 16px;
}
.clear{
color: #507AFD;
cursor: pointer;
}
}
}
.wrapper {
display: flex;
flex-direction: column;
.card-top{
padding: 24px;
}
&-title {
font-size: 18px;
font-family: PingFang SC, PingFang SC-Medium;
font-weight: 600;
color: #333333;
}
&-bar {
background-color: #e8e8e8;
width: 100%;
margin-top: 20px;
}
&-content {
flex: auto;
background: #fff;
margin-top: 20px;
}
&-footer {
display: flex;
justify-content: flex-end;
border-top: 0.5px solid #d9d9d9;
padding: 15px 24px;
}
&-info {
font-weight: bold;
position: relative;
height: 29px;
background: #f8f8f8;
font-size: 16px;
font-family: PingFang SC, PingFang SC-Medium;
font-weight: 600;
color: #333333;
display: flex;
align-items: center;
padding-left: 14px;
&:before {
background-color: #507AFD;
content: "";
height: 18px;
width: 4px;
border-radius: 3px;
top: 5px;
left: 0;
position: absolute;
}
}
}
.cardstyle {
width: 820px;
height: 800px;
--n-padding-bottom: 20px;
--n-padding-left: 24px;
}
::v-deep(.n-card.n-card--content-segmented > .n-card__content:not(:first-child)) {
border: 0px;
}
::v-deep(.n-card > .n-card-header) {
--n-padding-top: 0px;
--n-padding-bottom: 12px;
}
::v-deep(.n-card__content) {
padding: 0!important;
}
::v-deep(.n-data-table .n-data-table-td) {
padding: 10px 12px!important;
}
.btn1{
background: #507AFD;
}
.btn{
border: 1px solid #cad2dd;
background-color: #fff;
}
.btn-batch {
width: 118px;
height: 36px;
background: linear-gradient(135deg, #5b85f8, #3c6cf0);
border-radius: 17px;
box-shadow: 0px 2px 6px 0px rgba(116, 153, 253, 0.3);
display: flex;
align-items: center;
justify-content: center;
color: #fff;
margin-right: 6px;
cursor: pointer;
}
</style>