|
|
|
@ -1,4 +1,5 @@
|
|
|
|
|
<script lang="ts" setup>
|
|
|
|
|
import { audit } from '@/api/task/task';
|
|
|
|
|
import {
|
|
|
|
|
clearTF, getTaskDetailInfo,
|
|
|
|
|
getTaskDetailPictureList,
|
|
|
|
@ -10,6 +11,7 @@ import { useWorkOrder } from "@/store/modules/workOrder";
|
|
|
|
|
import { isEmpty } from "@/utils";
|
|
|
|
|
import { formatToDateHMS } from "@/utils/dateUtil";
|
|
|
|
|
import { hideDownload } from "@/utils/image";
|
|
|
|
|
import emitter from '@/utils/mitt';
|
|
|
|
|
import { useInfiniteScroll } from "@vueuse/core";
|
|
|
|
|
import { format } from 'date-fns';
|
|
|
|
|
import imagesloaded from "imagesloaded";
|
|
|
|
@ -17,7 +19,7 @@ import { clone, debounce, pickBy } from "lodash-es";
|
|
|
|
|
import { useDialog, useMessage } from "naive-ui";
|
|
|
|
|
import { computed, onUnmounted, onUpdated, reactive, ref, unref, watch } from "vue";
|
|
|
|
|
import ConfrimModal from "../modal/ConfrimModal.vue";
|
|
|
|
|
import type { SetTFParam, SimilarityPictureSortParam } from "/#/api";
|
|
|
|
|
import type { ApprovalParam, SetTFParam, SimilarityPictureSortParam } from "/#/api";
|
|
|
|
|
|
|
|
|
|
const batch = ref(false);
|
|
|
|
|
const selectItems = ref<any[]>([]);
|
|
|
|
@ -68,7 +70,7 @@ const imageRef = ref<ComponentElRef | null>();
|
|
|
|
|
const listData = ref<any[]>([]);
|
|
|
|
|
const loading = ref(false);
|
|
|
|
|
const el = ref<HTMLDivElement | null>(null);
|
|
|
|
|
|
|
|
|
|
const selectedSortName = ref('');
|
|
|
|
|
let canloadMore = true;
|
|
|
|
|
|
|
|
|
|
let processItems: any[] = [];
|
|
|
|
@ -312,7 +314,7 @@ async function handleSelect(item: any) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function sortHandler(orderby: "similarityScore" | "createdate") {
|
|
|
|
|
|
|
|
|
|
selectedSortName.value = orderby;
|
|
|
|
|
sortBy.orderName = orderby;
|
|
|
|
|
sortBy.orderType = sortBy.orderType === "asc" ? "desc" : "asc";
|
|
|
|
|
refreshHandler();
|
|
|
|
@ -399,6 +401,102 @@ function previewHandler(event: MouseEvent) {
|
|
|
|
|
if (imageRef.value && (imageRef.value as any).src)
|
|
|
|
|
(imageRef.value as any).mergedOnClick();
|
|
|
|
|
}
|
|
|
|
|
function rejectHandler(items?: any) {
|
|
|
|
|
let cloneItem: any
|
|
|
|
|
if (batch.value) {
|
|
|
|
|
processItems = selectItems.value
|
|
|
|
|
}
|
|
|
|
|
else if (overTask.value) {
|
|
|
|
|
cloneItem = clone(overTask.value)
|
|
|
|
|
processItems = [cloneItem]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (items !== undefined && !(items instanceof PointerEvent))
|
|
|
|
|
processItems = items
|
|
|
|
|
|
|
|
|
|
const msg = validate(processItems)
|
|
|
|
|
|
|
|
|
|
if (msg !== null) {
|
|
|
|
|
message.error(msg)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const modal = unref(confrimModalRef)! as any
|
|
|
|
|
modal.showModal()
|
|
|
|
|
}
|
|
|
|
|
function reject(idOrDesc: string, backId: string, isOther: boolean) {
|
|
|
|
|
const formIds: string[] = processItems.map(item => item.id)
|
|
|
|
|
const taskIds: string[] = processItems.map(item => item.taskId)
|
|
|
|
|
const tasknames: string[] = processItems.map(item => item.taskname)
|
|
|
|
|
|
|
|
|
|
const param: ApprovalParam = {
|
|
|
|
|
formid: formIds,
|
|
|
|
|
taskId: taskIds,
|
|
|
|
|
approvd: false,
|
|
|
|
|
taskComment: idOrDesc,
|
|
|
|
|
taskname: isOther ? tasknames : ['其他'],
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
doAudit(param)
|
|
|
|
|
}
|
|
|
|
|
function doAudit(param: any) {
|
|
|
|
|
audit(param).then((res) => {
|
|
|
|
|
const { code } = res
|
|
|
|
|
setBatch(false)
|
|
|
|
|
if (code === 'OK'){
|
|
|
|
|
emitter.emit('refresh')
|
|
|
|
|
refreshHandler()
|
|
|
|
|
}
|
|
|
|
|
else message.error(res.message)
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function approvalHandler(items?: any) {
|
|
|
|
|
let cloneItem: any
|
|
|
|
|
if (batch.value) {
|
|
|
|
|
processItems = selectItems.value
|
|
|
|
|
}
|
|
|
|
|
else if (overTask.value) {
|
|
|
|
|
cloneItem = clone(overTask.value)
|
|
|
|
|
processItems = [cloneItem]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (items !== undefined && !(items instanceof PointerEvent))
|
|
|
|
|
processItems = items
|
|
|
|
|
|
|
|
|
|
const msg = validate(processItems)
|
|
|
|
|
|
|
|
|
|
if (msg !== null) {
|
|
|
|
|
message.error(msg)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dialog.info({
|
|
|
|
|
title: '确认提示',
|
|
|
|
|
content: '确认给该任务审批为【通过】吗?',
|
|
|
|
|
positiveText: '确定',
|
|
|
|
|
negativeText: '取消',
|
|
|
|
|
onPositiveClick: () => {
|
|
|
|
|
approval()
|
|
|
|
|
},
|
|
|
|
|
onNegativeClick: () => {},
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
function approval() {
|
|
|
|
|
const formIds: string[] = processItems.map(item => item.id)
|
|
|
|
|
const taskIds: string[] = processItems.map(item => item.taskId)
|
|
|
|
|
const tasknames: string[] = processItems.map(item => item.taskname)
|
|
|
|
|
|
|
|
|
|
const param: ApprovalParam = {
|
|
|
|
|
formid: formIds,
|
|
|
|
|
taskId: taskIds,
|
|
|
|
|
approvd: true,
|
|
|
|
|
taskComment: 'approval',
|
|
|
|
|
taskname: tasknames,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
doAudit(param)
|
|
|
|
|
}
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<template>
|
|
|
|
@ -411,15 +509,17 @@ function previewHandler(event: MouseEvent) {
|
|
|
|
|
</div>
|
|
|
|
|
<div class="right">
|
|
|
|
|
<div v-show="!showActions" style="display: flex; align-items: center">
|
|
|
|
|
<n-button text @click="clearHandler">
|
|
|
|
|
<SvgIcon size="12" name="delete" />
|
|
|
|
|
清除标记
|
|
|
|
|
</n-button>
|
|
|
|
|
<div class="btn" style="margin: 0px 10px" @click="setBatch(true)">
|
|
|
|
|
<SvgIcon style="margin-right: 6px" size="14" name="tf" />
|
|
|
|
|
辨别真假
|
|
|
|
|
批量审批
|
|
|
|
|
</div>
|
|
|
|
|
<div class="icon-wrap">
|
|
|
|
|
<SvgIcon
|
|
|
|
|
size="20"
|
|
|
|
|
name="immersion-model"
|
|
|
|
|
@click="immersionHandler"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
<SvgIcon style="cursor: pointer" size="20" name="immersion-model" @click="immersionHandler" />
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div v-show="showActions" class="batch">
|
|
|
|
@ -429,12 +529,15 @@ function previewHandler(event: MouseEvent) {
|
|
|
|
|
</template>
|
|
|
|
|
返回
|
|
|
|
|
</n-button>
|
|
|
|
|
<div style="cursor: pointer; margin-left: 16px" @click="falseHandler">
|
|
|
|
|
<SvgIcon width="64" height="28" name="t4" />
|
|
|
|
|
<div
|
|
|
|
|
style="cursor: pointer; margin-left: 16px"
|
|
|
|
|
@click.stop="rejectHandler"
|
|
|
|
|
>
|
|
|
|
|
<SvgIcon width="64" height="28" name="a1" />
|
|
|
|
|
</div>
|
|
|
|
|
<SvgIcon size="24" name="vs" />
|
|
|
|
|
<div style="cursor: pointer" @click="trueHandler">
|
|
|
|
|
<SvgIcon width="64" height="28" name="t3" />
|
|
|
|
|
<div style="cursor: pointer" @click.stop="approvalHandler">
|
|
|
|
|
<SvgIcon width="64" height="28" name="a2" />
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
@ -446,21 +549,18 @@ function previewHandler(event: MouseEvent) {
|
|
|
|
|
<!-- 左侧大图 图片信息 -->
|
|
|
|
|
<div class="left" :style="{ 'background-image': `url(${taskDetailInfo?.imgurl})` }" @click="showAction"
|
|
|
|
|
@mouseleave="leaveTaskHandler">
|
|
|
|
|
<!-- 真假标记 -->
|
|
|
|
|
<div class="mark">
|
|
|
|
|
<SvgIcon v-show="taskDetailInfo?.iztrueorfalse === 0" size="128" name="jia" />
|
|
|
|
|
</div>
|
|
|
|
|
<div class="mark">
|
|
|
|
|
<SvgIcon v-show="taskDetailInfo?.iztrueorfalse === 1" size="128" name="zhen" />
|
|
|
|
|
</div>
|
|
|
|
|
<div class="footer-times">
|
|
|
|
|
<div class="time" style="margin-bottom: 4px;">
|
|
|
|
|
<SvgIcon color="#FFF" size="16" name="camera" />
|
|
|
|
|
<span class="time-value">{{ taskDetailInfo.createTime }} </span>
|
|
|
|
|
<span class="time-value">{{ taskDetailInfo?.submitDateTimestamp ? format(
|
|
|
|
|
taskDetailInfo.submitDateTimestamp, 'yyyy-MM-dd HH:mm:ss') : '-' }} </span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="time">
|
|
|
|
|
<SvgIcon color="#FFF" size="16" name="save" />
|
|
|
|
|
<span class="time-value">{{ taskDetailInfo.createTime }} </span>
|
|
|
|
|
<span class="time-value">{{
|
|
|
|
|
taskDetailInfo?.photoDateTimestamp ? format(taskDetailInfo?.photoDateTimestamp, 'yyyy-MM-dd HH:mm:ss') :
|
|
|
|
|
'-'
|
|
|
|
|
}} </span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="status">
|
|
|
|
@ -503,8 +603,8 @@ function previewHandler(event: MouseEvent) {
|
|
|
|
|
</div>
|
|
|
|
|
<!-- 操作 -->
|
|
|
|
|
<div v-show="overTask && overTask.id === taskDetailInfo.id" class="action" @click.stop="hideAction">
|
|
|
|
|
<SvgIcon style="cursor: pointer" name="t1" @click.stop="trueHandler" />
|
|
|
|
|
<SvgIcon style="cursor: pointer; margin-left: 30px" name="t2" @click.stop="falseHandler" />
|
|
|
|
|
<SvgIcon style="cursor: pointer" name="t1" @click.stop="approvalHandler" />
|
|
|
|
|
<SvgIcon style="cursor: pointer; margin-left: 30px" name="t2" @click.stop="rejectHandler" />
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<!-- 右侧任务 标题信息 -->
|
|
|
|
@ -512,8 +612,10 @@ function previewHandler(event: MouseEvent) {
|
|
|
|
|
<n-scrollbar style="max-height: 100%">
|
|
|
|
|
<span class="task-name">任务ID:{{ taskDetailInfo.taskname }}</span>
|
|
|
|
|
<div class="tags">
|
|
|
|
|
<div class="tag tag-approved">已审批</div>
|
|
|
|
|
<div class="tag tag-passed">通过</div>
|
|
|
|
|
<div class="tag tag-submiting" v-if="taskDetailInfo.states==1">{{ TASK_STATUS_OBJ[taskDetailInfo.states] }}</div>
|
|
|
|
|
<div class="tag tag-approve" v-else-if="taskDetailInfo.states==2">{{ TASK_STATUS_OBJ[taskDetailInfo.states] }}</div>
|
|
|
|
|
<div class="tag tag-passed" v-else-if="taskDetailInfo.states==3">{{ TASK_STATUS_OBJ[taskDetailInfo.states] }}</div>
|
|
|
|
|
<div class="tag tag-approved" v-else-if="taskDetailInfo.states==4">{{ TASK_STATUS_OBJ[taskDetailInfo.states] }}</div>
|
|
|
|
|
</div>
|
|
|
|
|
<n-divider class="divider-line" />
|
|
|
|
|
<div class="property">
|
|
|
|
@ -561,20 +663,23 @@ function previewHandler(event: MouseEvent) {
|
|
|
|
|
</n-scrollbar>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div style="display: flex; justify-content: space-between; padding: 12px 0px">
|
|
|
|
|
<div style="display: flex; justify-content: space-between; padding: 12px 0px 3px 0">
|
|
|
|
|
<div>
|
|
|
|
|
<!-- <span style="font-size: 21px; font-weight: bold">任务包图片</span><span>({{ totalCount }})</span> -->
|
|
|
|
|
<span
|
|
|
|
|
style="font-size: 18px; font-weight: Medium;color: #333333;font-family: PingFang SC, PingFang SC-Medium;">任务包图片</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div style="display: flex; align-items: center">
|
|
|
|
|
<div style="display: flex; align-items: center;font-size: 14px;margin-right: 25px;color:#323233">
|
|
|
|
|
<div style="cursor: pointer" @click="sortHandler('createdate')">
|
|
|
|
|
<span>时间排序</span>
|
|
|
|
|
<SvgIcon style="margin-left: 8px" name="sort" size="12" />
|
|
|
|
|
<SvgIcon style="margin-left: 5px" name="sort" size="12" v-show="selectedSortName !== 'createdate'" />
|
|
|
|
|
<SvgIcon style="margin-left: 5px" name="active-sort" size="12" v-show="selectedSortName === 'createdate'" />
|
|
|
|
|
</div>
|
|
|
|
|
<div style="margin-left: 15px; cursor: pointer" @click="sortHandler('similarityScore')">
|
|
|
|
|
<span>相似度排序</span>
|
|
|
|
|
<SvgIcon style="margin-left: 8px" name="sort" size="12" />
|
|
|
|
|
<SvgIcon style="margin-left: 5px" name="sort" size="12" v-show="selectedSortName !== 'similarityScore'" />
|
|
|
|
|
<SvgIcon style="margin-left: 5px" name="active-sort" size="12"
|
|
|
|
|
v-show="selectedSortName === 'similarityScore'" />
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
@ -586,12 +691,14 @@ function previewHandler(event: MouseEvent) {
|
|
|
|
|
<div class="time-wrapper">
|
|
|
|
|
<div class="time">
|
|
|
|
|
<SvgIcon color="#FFF" size="16" name="camera" />
|
|
|
|
|
<span class="current-time" >{{ item.photoDateTimestamp ? formatToDateHMS(Number(item.photoDateTimestamp) || 0) : '-'
|
|
|
|
|
<span class="current-time">{{ item.photoDateTimestamp ? formatToDateHMS(Number(item.photoDateTimestamp) ||
|
|
|
|
|
0) : '-'
|
|
|
|
|
}}</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="time">
|
|
|
|
|
<SvgIcon color="#FFF" size="16" name="save" />
|
|
|
|
|
<span class="current-time">{{ item.submitDateTimestamp ? formatToDateHMS(Number(item.submitDateTimestamp) || 0) : '-'
|
|
|
|
|
<span class="current-time">{{ item.submitDateTimestamp ? formatToDateHMS(Number(item.submitDateTimestamp)
|
|
|
|
|
|| 0) : '-'
|
|
|
|
|
}}</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
@ -605,30 +712,27 @@ function previewHandler(event: MouseEvent) {
|
|
|
|
|
{{ item?.maxSimilarity && Number(item?.maxSimilarity).toFixed(0) }}%
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="pass-status" v-if="item.historyStates === 1">
|
|
|
|
|
<SvgIcon name="repeat-icon" style="width:52;height:24px" />
|
|
|
|
|
</div>
|
|
|
|
|
<div class="pass-status" v-else-if="item.historyStates === 2">
|
|
|
|
|
|
|
|
|
|
<div class="pass-status" v-if="item.historyStates === 2">
|
|
|
|
|
<SvgIcon name="pass-icon" style="width:52;height:24px" />
|
|
|
|
|
</div>
|
|
|
|
|
<div class="pass-status" v-else-if="item.historyStates === 3">
|
|
|
|
|
<SvgIcon name="no-pass-icon" style="width:52;height:24px" />
|
|
|
|
|
</div>
|
|
|
|
|
<!-- <div class="mark">
|
|
|
|
|
<SvgIcon name="jia" />
|
|
|
|
|
</div>
|
|
|
|
|
<div class="mark">
|
|
|
|
|
<SvgIcon name="zhen" />
|
|
|
|
|
<!--
|
|
|
|
|
重复标签
|
|
|
|
|
<div class="pass-status" v-if="item.historyStates === 1">
|
|
|
|
|
<SvgIcon name="repeat-icon" style="width:52;height:24px" />
|
|
|
|
|
</div> -->
|
|
|
|
|
<div v-show="overTask && overTask.id === item.id" class="action">
|
|
|
|
|
<SvgIcon style="cursor: pointer" name="t1" @click.stop="trueHandler" />
|
|
|
|
|
<SvgIcon style="cursor: pointer" name="t2" @click.stop="falseHandler" />
|
|
|
|
|
<SvgIcon style="cursor: pointer" name="t1" @click.stop="approvalHandler" />
|
|
|
|
|
<SvgIcon style="cursor: pointer;margin-left: 40px;" name="t2" @click.stop="rejectHandler" />
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</n-spin>
|
|
|
|
|
<ConfrimModal ref="confrimModalRef" @commit="setFalse" />
|
|
|
|
|
<ConfrimModal ref="confrimModalRef" @commit="reject" />
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
@ -795,7 +899,7 @@ function previewHandler(event: MouseEvent) {
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
background-color: rgba(102, 102, 102, 0.5);
|
|
|
|
|
background-color: rgba(0,0,0,0.48);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.info {
|
|
|
|
@ -810,6 +914,17 @@ function previewHandler(event: MouseEvent) {
|
|
|
|
|
padding: 16px 0 0 23px;
|
|
|
|
|
color: #fff;
|
|
|
|
|
}
|
|
|
|
|
.icon-wrap{
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
width: 30px;
|
|
|
|
|
height: 30px;
|
|
|
|
|
background: rgba(80,122,253,.1);
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
margin-left: 10px;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.img-info {
|
|
|
|
|
color: lime !important;
|
|
|
|
@ -905,7 +1020,14 @@ function previewHandler(event: MouseEvent) {
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
line-height: 16px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.tag-submiting{
|
|
|
|
|
color: #feaf2d;
|
|
|
|
|
border: 1px solid #feaf2d;
|
|
|
|
|
}
|
|
|
|
|
.tag-approve{
|
|
|
|
|
color: #398ade;
|
|
|
|
|
border: 1px solid #398ade;
|
|
|
|
|
}
|
|
|
|
|
.tag-passed {
|
|
|
|
|
color: #02C984;
|
|
|
|
|
border: 1px solid #02C984;
|
|
|
|
@ -1055,8 +1177,8 @@ function previewHandler(event: MouseEvent) {
|
|
|
|
|
display: flex;
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: space-around;
|
|
|
|
|
background-color: #666666;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
background-color: rgba(0,0,0,0.48);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|