feat: 修改bug

pull/41/head
raofuzi 1 year ago
commit f755c42976

8
components.d.ts vendored

@ -22,9 +22,12 @@ declare module 'vue' {
NDivider: typeof import('naive-ui')['NDivider']
NDropdown: typeof import('naive-ui')['NDropdown']
NEllipsis: typeof import('naive-ui')['NEllipsis']
NEllipsis: typeof import('naive-ui')['NEllipsis']
NEmpty: typeof import('naive-ui')['NEmpty']
NForm: typeof import('naive-ui')['NForm']
NFormItem: typeof import('naive-ui')['NFormItem']
NGi: typeof import('naive-ui')['NGi']
NGi: typeof import('naive-ui')['NGi']
NGrid: typeof import('naive-ui')['NGrid']
NGridItem: typeof import('naive-ui')['NGridItem']
NImage: typeof import('naive-ui')['NImage']
@ -34,6 +37,7 @@ declare module 'vue' {
NNotificationProvider: typeof import('naive-ui')['NNotificationProvider']
NotPassed: typeof import('./src/components/NotPassed.vue')['default']
NPopconfirm: typeof import('naive-ui')['NPopconfirm']
NPopconfirm: typeof import('naive-ui')['NPopconfirm']
NPopover: typeof import('naive-ui')['NPopover']
NPopselect: typeof import('naive-ui')['NPopselect']
NProgress: typeof import('naive-ui')['NProgress']
@ -43,7 +47,11 @@ declare module 'vue' {
NSpace: typeof import('naive-ui')['NSpace']
NSpin: typeof import('naive-ui')['NSpin']
NSwitch: typeof import('naive-ui')['NSwitch']
NTabPane: typeof import('naive-ui')['NTabPane']
NTabs: typeof import('naive-ui')['NTabs']
NTag: typeof import('naive-ui')['NTag']
NTimeline: typeof import('naive-ui')['NTimeline']
NTimelineItem: typeof import('naive-ui')['NTimelineItem']
NTooltip: typeof import('naive-ui')['NTooltip']
NUpload: typeof import('naive-ui')['NUpload']
NUploadDragger: typeof import('naive-ui')['NUploadDragger']

@ -30,11 +30,11 @@ export async function getFinalList(params: FinalParam) {
params: notEmptyParams,
})
const { data: { list, totalPage,totalCount } } = res
const { data: { list, totalPage, totalCount } } = res
return {
pageCount: totalPage,
data: list,
totalCount
totalCount,
}
}
@ -62,3 +62,22 @@ export async function repetitionTask() {
method: 'get',
})
}
/**
*
* @returns
*/
export async function getRepeatList(params: FinalParam) {
const res = await http.request({
url: `/flow/task/repetitionTaskList`,
method: 'get',
params,
})
const { data: { records, totalPage, totalCount } } = res
return {
pageCount: totalPage,
data: records,
totalCount,
}
}

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="64px" height="64px" viewBox="0 0 64 64" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>chazhongjiansuo</title>
<defs>
<rect id="path-1" x="0" y="0" width="64" height="64"></rect>
<linearGradient x1="12.4444444%" y1="0%" x2="87.5555556%" y2="100%" id="linearGradient-3">
<stop stop-color="#5B85F8" offset="0%"></stop>
<stop stop-color="#3C6CF0" offset="100%"></stop>
</linearGradient>
</defs>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="PrevailCloud-Design-图标集" transform="translate(-2250.000000, -6758.000000)">
<g id="chazhongjiansuo" transform="translate(2250.000000, 6758.000000)">
<mask id="mask-2" fill="white">
<use xlink:href="#path-1"></use>
</mask>
<g id="蒙版"></g>
<g mask="url(#mask-2)" fill="url(#linearGradient-3)" fill-rule="nonzero" id="形状结合">
<g transform="translate(6.000000, 2.000000)">
<path d="M31.4511232,24.8747904 L31.7607141,24.8786253 L32.4504148,24.8786253 C39.5888163,25.0499657 45.2098765,30.9440752 45.0374513,38.0375676 C44.9632519,41.0900989 43.8225861,43.8634128 41.9782017,46.0188901 L51.6240923,56.6794025 C52.1413678,57.2619598 52.1413678,57.8102491 51.5206372,58.3585383 L50.106751,59.6264573 C49.5205054,60.1404784 48.9687449,60.1404784 48.4169844,59.523653 L38.6877524,48.7707922 C36.6723213,49.9523783 34.3085739,50.605744 31.7951992,50.5454164 L31.7951992,50.5454164 L31.1054985,50.5454164 C23.967097,50.374076 18.3460368,44.4799664 18.518462,37.3864741 C18.6908871,30.2929817 24.6223126,24.7072849 31.7607141,24.8786253 Z M23.6222467,0.61682542 C24.5188575,-0.205608473 25.8982588,-0.205608473 26.7948696,0.61682542 C29.3467619,2.94705478 35.2781874,6.95642001 46.3478825,7.77885391 C48.6928647,7.9501943 50.4516013,9.9034748 50.4176147,12.1994361 L50.4176147,12.1994361 L50.4176147,38.1061037 L48.5894096,38.1061037 C49.106685,28.682382 41.8303434,20.6293835 32.3469597,20.1153623 C22.8290909,19.6013411 14.6906235,26.7976377 14.173348,36.2556275 C13.6560725,45.7136172 20.9324142,53.8008838 30.4157979,54.314905 C31.5538039,54.3834412 32.69181,54.314905 33.795331,54.1435646 L33.795331,54.1435646 L34.5540017,55.2744112 C32.5193848,56.5423302 30.553738,57.775981 28.6915463,58.8382914 C26.5534744,60.1747465 23.8291569,60.1747465 21.6910849,58.8382914 C14.7595935,54.4177093 0,44.1715537 0,37.5235464 L0,37.5235464 L0,12.1994361 C0,9.9034748 1.75873661,8.01873046 4.06923373,7.81312199 C15.0009888,6.99068809 21.0013843,2.94705478 23.6222467,0.61682542 Z M31.7951992,30.2244456 C27.6225103,30.1216413 24.1395221,33.3771088 24.0705521,37.5235464 C23.967097,41.6699839 27.243175,45.0967918 31.4158638,45.199596 L31.4158638,45.199596 L31.8296842,45.199596 C36.002373,45.3024003 39.4508762,42.0469328 39.5543313,37.9004952 C39.6577864,33.7540577 36.3817084,30.3272498 32.2090195,30.2244456 L32.2090195,30.2244456 Z"></path>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

@ -101,7 +101,7 @@ async function handleSumbit(e: MouseEvent) {
audit(param).then((res) => {
const { code } = res
if (code === 'OK') {
message.success('审核成功')
message.success(res.message)
emit('success', param)
closeModal()
}
@ -199,6 +199,8 @@ async function selectChange(id) {
justify-content: flex-end;
padding-right: 24px;
padding-bottom: 10px;
border-top: 0.5px solid #d9d9d9;
padding-top: 15px;
}
&-info {
@ -236,6 +238,10 @@ async function selectChange(id) {
margin-bottom: 0px;
}
::v-deep(.n-form-item-label__text) {
color: #666666;
}
::v-deep(.n-input__placeholder) {
color: #333333!important;
}

@ -8,7 +8,7 @@ export interface AsideEntity {
inFilterList?: boolean// 是否出现在过滤配置选项中(这个名字不好为false代表只用于客户端的显示配置不作为参数传递给服务器端)
render?: boolean// 是否作为单独组件渲染
key: string
component: Component
component?: Component
}
// 客户端配置

@ -1,5 +1,5 @@
import type { AsideEntity } from './aside'
import { IzProjectVue, IzStatus, IztaskrromVue, PictureDownloadVue, PlanVue, ReportUserVue, TimeVue } from '@/views/home/aside/comp/items'
import { IzProjectVue, IzStatus, IztaskrromVue, PictureDownloadVue, PlanVue, ReportUserVue, TimeVue, IzCustomname, IzCustomtype, IzVisitcity, IzCustomlevel, IzProjecttype, IzProductVue, IzvisitproVue, IzfirmVue } from '@/views/home/aside/comp/items'
export interface RowData {
id: string
@ -129,3 +129,99 @@ export const asideMap: Recordable<AsideEntity> = {
inFilterList: false,
},
}
// 审批添加筛选配置 (左侧)
export const asideTaskMap: Recordable<AsideEntity> = {
izstatus: {
label: '审批状态',
defaultValue: null,
isDefaultFilter: true,
key: 'izstatus',
component: IzStatus, // todo
},
izuptime: {
label: '提报时间',
defaultValue: null,
isDefaultFilter: true,
key: 'izuptime',
component: TimeVue,
},
izupuser: {
label: '提报人',
defaultValue: null,
isDefaultFilter: true,
key: 'izupuser',
component: ReportUserVue,
},
iztaskrrom: {
label: '任务来源',
defaultValue: null,
isDefaultFilter: true,
key: 'iztaskrrom',
component: IztaskrromVue,
},
izcustomname: {
label: '拜访客户',
defaultValue: null,
isDefaultFilter: true,
key: 'izcustomname',
component: IzCustomname,
},
izcustomtype: {
label: '客户类型',
defaultValue: null,
isDefaultFilter: true,
key: 'izcustomtype',
component: IzCustomtype,
},
izproject: {
label: '所属项目',
defaultValue: null,
isDefaultFilter: true,
key: 'izproject',
component: IzProjectVue,
},
izvisitpro: {
label: '拜访省份/直辖市',
defaultValue: null,
isDefaultFilter: true,
key: 'izvisitpro',
component: IzVisitcity,
},
izcustomlevel: {
label: '客户级别',
defaultValue: null,
isDefaultFilter: true,
key: 'izcustomlevel',
component: IzCustomlevel
},
izprojecttype: {
label: '项目类别',
defaultValue: null,
isDefaultFilter: true,
key: 'izprojecttype',
component: IzProjecttype,
},
izproductname: {
label: '产品名称',
defaultValue: null,
isDefaultFilter: true,
key: 'izproductname',
component: IzProductVue,
},
izvisitcity: {
label: '拜访城市',
defaultValue: null,
isDefaultFilter: true,
key: 'izvisitcity',
component: IzvisitproVue,
},
izfirm: {
label: '厂商',
defaultValue: null,
isDefaultFilter: true,
key: 'izfirm',
component: IzfirmVue,
}
}

@ -22,6 +22,7 @@ const { detail, total } = toRefs(state)
const show = ref(false)
function showModal(id) {
state.total = 0
getDetail(id)
}
@ -45,7 +46,13 @@ function closeModal() {
}
async function reject() {
emit('reject', { a: 'todo' })
const list = []
state.detail.forEach((items) => {
items.repeatedTaskList.forEach((item) => {
list.push(item)
})
})
emit('reject', list)
closeModal()
}
@ -157,7 +164,7 @@ defineExpose({
border-radius: 8px;
padding: 16px;
padding-top: 0;
margin: 45px 12px 35px 38px;
margin: 25px 12px 35px 38px;
.imgwrapper {
width: 160px;

@ -1,101 +1,148 @@
<script lang="ts" setup>
import { computed, h, reactive, ref, unref } from "vue";
import { NDataTable, useDialog } from "naive-ui";
import type { DataTableColumns, DataTableRowKey } from "naive-ui";
import Action from "../comp/Action.vue";
import { RejectModal } from "./index";
import type { RowData } from "@/config/final";
import { getFinalList } from "@/api/final";
import type { ApprovalParam } from "/#/api";
import { audit } from "@/api/task/task";
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 {
ListAction,
StatusItem,
} from '../comp'
import { RejectModal } from './index'
import { useDictionary } from '@/store/modules/dictonary'
import type { RowData } from '@/config/final'
import { getFinalList, 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 show = ref(false);
function showModal() {
show.value = true;
}
(e: 'commit', columns: any[])
}>()
const dicStore = useDictionary()
const message = useMessage()
const show = ref(false)
const izstatusList = ref([])
const dialog = useDialog()
const checkedRowKeys = ref([])
onBeforeMount(() => {
dicStore.fetchizstatusListt()
})
function closeModal() {
show.value = false;
show.value = false
}
async function handleSumbit(e: MouseEvent) {
e.preventDefault();
closeModal();
e.preventDefault()
closeModal()
}
defineExpose({
showModal,
});
const columns: DataTableColumns<RowData> = [
{
type: "selection",
fixed: "left",
type: 'selection',
fixed: 'left',
width: 50,
disabled(row: any) {
return row.states !== 2
},
},
{
title: "任务Id",
key: "id",
fixed: "left",
width: 100,
title: '任务Id',
key: 'id',
fixed: 'left',
width: 180,
ellipsis: {
tooltip: true,
},
},
{
title: "任务名称",
key: "fromtaskname",
fixed: "left",
width: 200,
title: '任务名称',
key: 'fromtaskname',
fixed: 'left',
width: 150,
ellipsis: {
tooltip: true,
},
},
{
title: "审批节点",
key: "approvalnode",
title: '审批节点',
key: 'approvalnode',
width: 100,
},
{
title: "审批状态",
key: "states",
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: "similarity",
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",
title: '提报时间',
key: 'fromuptime',
width: 200,
render(row: any) {
return formatToDateHMS(row.createdate || 0)
},
},
{
title: "更新时间",
key: "updatetime",
title: '更新时间',
key: 'updatetime',
width: 200,
},
{
title: "操作",
key: "actions",
title: '操作',
key: 'actions',
width: 200,
fixed: "right",
fixed: 'right',
render(row) {
return h(Action, {
return h(ListAction, {
id: row.id,
status: row.states,
trigger: actionHandler,
});
trigger: (action) => {
actionHandler(action, row)
},
})
},
},
];
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 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,
@ -103,136 +150,220 @@ const pagination = reactive({
showSizePicker: true,
pageSizes: [
{
label: "10 每页",
label: '10 每页',
value: 10,
},
{
label: "15 每页",
label: '15 每页',
value: 15,
},
{
label: "30 每页",
label: '30 每页',
value: 30,
},
{
label: "50 每页",
label: '50 每页',
value: 50,
},
],
showQuickJumper: true,
prefix:()=>`${total.value} 条数据`
});
const tableData = ref<Array<RowData>>([]);
const selectionIds = ref<DataTableRowKey[]>([]);
prefix: () => `${total.value} 条数据`,
})
const tableData = ref<Array<RowData>>([])
const selectionIds = ref<DataTableRowKey[]>([])
const deviceHeight = ref(600);
const deviceHeight = ref(500)
const maxHeight = computed(() => {
return tableData.value.length ? `${unref(deviceHeight)}px` : "auto";
});
return tableData.value.length ? `${unref(deviceHeight)}px` : 'auto'
})
async function query(page: number, pageSize: number) {
const result = await getFinalList({
sortorder: "asc",
pageSize: 10,
currPage: 1,
sortname: "",
});
const { data, pageCount,totalCount } = result;
total.value = totalCount;
tableData.value = data;
pagination.page = page;
pagination.pageCount = pageCount;
loading.value = false;
const result = await getRepeatList({
sortorder: 'asc',
pageSize: pagination.pageSize,
pageNo: 1,
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);
if (loading.value)
return
pagination.page = currentPage
const { pageSize } = pagination
await query(currentPage, pageSize)
}
async function handlePageSizeChange(currentPageSize) {
if (loading.value) return;
if (loading.value)
return
const { page } = pagination;
pagination.pageSize = currentPageSize;
const { page } = pagination
pagination.pageSize = currentPageSize
await query(page, currentPageSize);
await query(page, currentPageSize)
}
function handleCheck(rowKeys: DataTableRowKey[]) {
selectionIds.value = rowKeys;
selectionIds.value = rowKeys
}
function validate(items: any[]) {
if (items.length === 0)
return '至少选中一个任务'
return null
}
function actionHandler(action: any) {
const { key } = action;
function actionHandler(action: any, row: any) {
const { key } = action
switch (key) {
case "view":
break;
case "reset":
resetHandler();
break;
case "approval":
approvalHandler();
break;
case "reject":
(rejectModalRef.value as any).showModal();
break;
case 'view':
break
case 'reset':
// resetHandler()
break
case 'approval':
singleApproval(row)
break
case 'reject':
rejectHandler([row])
break
default:
break;
break
}
}
const dialog = useDialog();
function getSelectItems() {
return tableData.value.filter(item => selectionIds.value.includes(item.id))
}
function resetHandler() {
dialog.info({
title: "确认提示",
content: "确认重置当前选中的任务的审批吗?",
positiveText: "确定",
negativeText: "取消",
onPositiveClick: async () => {
// TODO
// const result = await resetApproval()
},
onNegativeClick: () => {},
});
//
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 approvalHandler() {
//
function doAudit(param: any) {
dialog.info({
title: "确认提示",
content: "确认给该任务审批为【通过】吗?",
positiveText: "确定",
negativeText: "取消",
title: '确认提示',
content: '确认给该任务审批为【通过】吗?',
positiveText: '确定',
negativeText: '取消',
onPositiveClick: () => {
// TODO
audit(param).then((res) => {
const { code } = res
if (code === 'OK') {
message.success(res.message)
reload()
}
else { message.error(res.message) }
})
},
onNegativeClick: () => {},
});
})
}
function rejectHandler(idOrDesc: string, isOther: boolean) {
// TODO:
// const param: ApprovalParam = {
// formid: '',
// taskId: '',
// approvd: false,
// taskComment: '',
// }
// if (isOther)
// param.taskComment = idOrDesc
// else
// param.taskComment = idOrDesc
// audit(param)
//
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)
query(pagination.page, pagination.pageSize);
show.value = true
}
function reload() {
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"
@ -248,9 +379,15 @@ query(pagination.page, pagination.pageSize);
<span :style="{ 'margin-left': '18px' }">任务信息</span>
</div>
</div>
<div class="batch">
<img class="btn-approval btn-left" 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="wrapper-content">
<NDataTable
ref="tableRef"
v-model:checked-row-keys="checkedRowKeys"
remote
:columns="columnsRef"
:scroll-x="1250"
@ -267,7 +404,9 @@ query(pagination.page, pagination.pageSize);
</div>
<template #footer>
<div class="wrapper-footer">
<n-button type="info" @click="handleSumbit"> </n-button>
<n-button type="info" @click="handleSumbit">
确认
</n-button>
<n-button secondary style="margin-left: 15px" @click="closeModal">
取消
</n-button>
@ -280,6 +419,18 @@ query(pagination.page, pagination.pageSize);
</template>
<style lang="less" scoped>
.batch {
display: flex;
align-items: center;
margin-top: 27px;
.btn-approval{
width: 68px;
height: 28px;
cursor: pointer;
}
}
.wrapper {
display: flex;
flex-direction: column;

@ -505,7 +505,7 @@ query(pagination.page, pagination.pageSize)
const customTabelRef = ref(null)
const importExcelRef = ref(null)
const notPassModalRef = ref(null) //
const notPassModalRef = ref(null) //
const repeatModalRef = ref(null)
const repeatTaskTableModalRef = ref(null)
@ -682,6 +682,12 @@ function batchApproval() {
doAudit(param)
}
//
function repeatBatchReject(items) {
console.log(items)
rejectHandler(items)
}
//
function batchReject() {
const items: any = getSelectItems()
@ -700,6 +706,27 @@ function rejectHandler(list) {
modal.showModal(list)
}
//
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 reload() {
selectionIds.value = []
checkedRowKeys.value = []
@ -725,27 +752,6 @@ async function refreshHandler(searchId?: any) {
reset()
query(pagination.page, pagination.pageSize, searchId)
}
//
function doAudit(param: any) {
dialog.info({
title: '确认提示',
content: '确认给该任务审批为【通过】吗?',
positiveText: '确定',
negativeText: '取消',
onPositiveClick: () => {
audit(param).then((res) => {
const { code } = res
if (code === 'OK') {
message.success('审核成功')
reload()
}
else { message.error(res.message) }
})
},
onNegativeClick: () => {},
})
}
</script>
<template>
@ -756,6 +762,7 @@ function doAudit(param: any) {
<SvgIcon size="32" name="magnifying" @click="changeContent" />
</div>
<div>
<SvgIcon style="margin-right: 6px;" size="13" name="summary" @click="showModal(repeatModalRef)" />
<NButton class="xjcc" text @click="showModal(repeatModalRef)">
小结查重
</NButton>
@ -842,7 +849,7 @@ function doAudit(param: any) {
<RepeatModal
ref="repeatModalRef"
@reject="showModal(notPassModalRef)"
@reject="repeatBatchReject"
@viewrepeat="showModal(repeatTaskTableModalRef)"
/>
<RepeatTaskTableModal ref="repeatTaskTableModalRef" />

@ -20,6 +20,13 @@ import type { FilterSearchParam } from "/#/api";
defineOptions({ name: "FilterModal" });
const props = defineProps({
type: {
type: Number,
default: () => 0,
},
});
const emit = defineEmits<{
(e: "showNewFilter"): void;
(e: "editFilter", filter: any): void;
@ -56,7 +63,9 @@ const sortData = (row) => {
new Date(b[row.columnKey]).getTime() - new Date(a[row.columnKey]).getTime()
);
} else {
tableData.value.sort((a, b) => Number((a as any).reorder) - Number((b as any).reorder));
tableData.value.sort(
(a, b) => Number((a as any).reorder) - Number((b as any).reorder)
);
}
};
@ -142,7 +151,7 @@ async function query(page: number, pageSize: number) {
const searchParam: FilterSearchParam = {
search_searchname: { value: keyword.value, op: "like", type: "string" },
};
const result = await getConditionList({ pageNo: page, pageSize }, searchParam, 0);
const result = await getConditionList({ pageNo: page, pageSize }, searchParam, props.type);
const { data, pageCount, total: totalCount } = result;
tableData.value = data;
pagination.page = page;
@ -440,7 +449,7 @@ const inputHandler = debounce((word) => {
}
}
}
::v-deep(.n-data-table .n-data-table-th){
::v-deep(.n-data-table .n-data-table-th) {
font-weight: bold !important;
}
</style>

@ -210,6 +210,8 @@ watch(() => dicStore.relationTypeList, (newval) => {
})
function showModal() {
const list = generateAllData(configStore.systemConfig)
typeOptions.value = list
show.value = true
}

@ -300,7 +300,11 @@ async function sendCode(value) {
phone: formSms.phone,
agentcode: formSms.agentcode,
});
startCount();
if(res.code == 'OK'){
startCount();
}else{
message.error(res.message)
}
}
function startCount() {

@ -1,21 +1,19 @@
<script lang="ts" setup>
import { debounce } from 'lodash-es'
import { computed, inject, onMounted, ref, shallowRef, unref, watch } from 'vue'
import { computed, inject, onBeforeMount, onMounted, ref, shallowRef, unref, watch } from 'vue'
import CustomFieldModal from '../modal/CustomFieldModal.vue'
import AdvanceFilter from '../../home/aside/comp/AdvanceFilter.vue'
import {
FilterModalVue,
NewFilterModalVue,
} from '../../home/aside/comp/modals'
import NewFilterModalVue from '../modal/NewFilterModal.vue'
import TaskList from './TaskList.vue'
import type { AsideEntity } from '@/config/aside'
import { useUser } from '@/store/modules/user'
import { getAllfieldList, getfieldList } from '@/api/home/filter'
import { useTaskStore } from '@/store/modules/task'
import emitter from '@/utils/mitt'
import { useConfig } from '@/store/modules/asideConfig'
const CustomFieldModalRef = ref(null)
const collapse = ref(false)
@ -87,8 +85,8 @@ async function getshowFieldList() {
* fix 是否默认
* checked 是否选中
*/
if (useList.userFieldFixed) {
useList.userFieldFixed?.split(',').map((v) => {
if (useList?.userFieldFixed) {
useList?.userFieldFixed?.split(',').map((v) => {
let item = allList.find(v2 => v2.name == v)
if (item) {
item = {
@ -103,7 +101,7 @@ async function getshowFieldList() {
}
else {
//
allList.map((v) => {
allList?.map((v) => {
if (v.isrequired == 2) {
const item = {
name: v.fieldDesc,
@ -144,7 +142,11 @@ function editFilter(filter: any) {
modal.showModal()
modal.edit(filter)
}
const configStore = useConfig()
onBeforeMount(async () => {
configStore.fetchConfig()
configStore.fetchCustomConfig()
})
function setAsideItemName(text) {
taskListRef.value.setStatusName(text)
}
@ -231,6 +233,7 @@ defineExpose({
ref="filterModalRef"
@edit-filter="editFilter"
@show-new-filter="showModal(newFilterModalRef)"
:type="2"
/>
<!-- 新增过滤 -->
<NewFilterModalVue ref="newFilterModalRef" />

@ -2,7 +2,7 @@
import { computed, onMounted, onUnmounted, reactive, ref, unref, watch } from 'vue'
import { chunk, clone } from 'lodash-es'
import { useDialog, useMessage } from 'naive-ui'
import { useRoute } from 'vue-router'
import { useRoute, useRouter } from 'vue-router'
import BatchModal from '../modal/BatchModal.vue'
import CustomSettingModal from '../modal/CustomSettingModal.vue'
import PictureTable from './PictureTable.vue'
@ -25,6 +25,9 @@ import { formatToDateHMS } from '@/utils/dateUtil'
import { hideDownload } from '@/utils/image'
const emit = defineEmits(['setAsideItemName'])
const router = useRouter()
const batch = ref(false)
const selectItems = ref<any[]>([])
const message = useMessage()
@ -37,22 +40,12 @@ const packageId: any = ref('') // 包id
const CustomSettingModalRef = ref(null)
const taskTableData = ref<any[]>([])
const route = useRoute()
const isDetail = ref(false) //
const sortBy: any = {
orderType: 'desc',
orderName: 'similarityScore',
}
function setBatch(value: boolean) {
if (totalCount.value === 0)
return
batch.value = value
if (value === false)
selectItems.value = []
}
function onCheckChange(checked: any, item: any) {
const index = selectItems.value.indexOf(item)
item.checked = checked
@ -77,12 +70,23 @@ const taskDetailPictureList = ref<any[]>([])
const userStore = useUser()
const imageRef = ref<ComponentElRef | null>()
let processItems: any[] = []
const isFullScreen = ref(false)
const fullscreenStyles = computed<any>(() => ({
width: isFullScreen.value ? '100vw' : '',
height: isFullScreen.value ? '100vh' : '',
position: isFullScreen.value ? 'fixed' : '',
top: isFullScreen.value ? '0' : '',
left: isFullScreen.value ? '0' : '',
zIndex: isFullScreen.value ? '9999' : '',
}))
onMounted(() => {
window.addEventListener('keydown', handleKeydown)
if (route.query.id) {
taskId.value = route.query.id
packageId.value = route.query.packageid
isDetail.value = true
getDetail()
}
})
@ -97,6 +101,21 @@ function handleKeydown(event) {
//
}
function setBatch(value: boolean) {
// if (totalCount.value === 0)
// return
batch.value = value
if (value === false) {
taskDetailInfo.value.checked = false
selectItems.value = []
taskDetailPictureList.value.forEach((item) => {
item.checked = false
})
}
}
// storeid
function currentTaskId() {
const index = taskStore.getCurrentIndex
@ -191,7 +210,7 @@ function doAudit(param: any) {
audit(param).then((res) => {
const { code } = res
if (code === 'OK') {
message.success('审核成功')
message.success(res.message)
setBatch(false)
reloadList(param, '通过')
}
@ -299,9 +318,13 @@ onUnmounted(() => {
})
function immersionHandler() {
taskStore.updateImmersion()
// taskStore.updateImmersion()
toggleFullScreen()
}
//
function toggleFullScreen() {
isFullScreen.value = !isFullScreen.value
}
function previewHandler(event: MouseEvent) {
event.stopImmediatePropagation()
event.stopPropagation()
@ -339,19 +362,29 @@ function reloadList(param, text) {
getDetail()
}
function goBack() {
router.back()
}
function switchBatch() {
setBatch(!batch.value)
}
</script>
<template>
<div class="wrapper">
<div class="wrapper fullscreen-container" :style="fullscreenStyles">
<div class="wrapper-header">
<div class="left">
<span class="font">任务ID{{ taskDetailInfo.fromtaskname }}</span>
<SvgIcon size="22" class="forward" name="arrow-left" @click="backHandler" />
<SvgIcon size="22" class="back" name="arrow-right" @click="forwardHandler" />
<template v-if="!isDetail">
<SvgIcon size="22" class="forward" name="arrow-left" @click="backHandler" />
<SvgIcon size="22" class="back" name="arrow-right" @click="forwardHandler" />
</template>
</div>
<div class="right">
<div v-if="!isDetail" class="right">
<div v-show="!showActions" style="display: flex; align-items: center">
<div class="btn" @click="setBatch(true)">
<div class="btn" @click="switchBatch()">
<SvgIcon style="margin-right: 6px" size="22" name="batch" />
批量审批
</div>
@ -381,11 +414,12 @@ function reloadList(param, text) {
</ul>
</n-popover> -->
<div class="icon-wrap">
<SvgIcon size="20" name="immersion-model" @click="immersionHandler" />
<SvgIcon v-if="isFullScreen" size="20" name="power-off" style="cursor: pointer;" @click="immersionHandler" />
<SvgIcon v-else size="20" name="immersion-model" style="cursor: pointer;" @click="immersionHandler" />
</div>
</div>
<div v-show="showActions" class="batch">
<n-button text @click="setBatch(false)">
<n-button text @click="switchBatch()">
<template #icon>
<SvgIcon name="revoke" />
</template>
@ -406,6 +440,14 @@ function reloadList(param, text) {
>
</div>
</div>
<div v-else class="right">
<n-button text @click="goBack">
<template #icon>
<SvgIcon name="revoke" />
</template>
返回
</n-button>
</div>
</div>
<div class="wrapper-detail">
<div
@ -603,10 +645,17 @@ function reloadList(param, text) {
@reject="rejectHandler"
@approval="approvalHandler"
/>
<CustomSettingModal ref="CustomSettingModalRef" />
</div>
</template>
<style lang="less" scoped>
.fullscreen-container {
/* 可添加其他样式 */
width: 100vw;
height: 100vh;
margin: 0px !important;
}
::v-deep(.n-tabs-tab__label) {
font-size: 14px;
font-family: PingFang SC, PingFang SC-Regular;

@ -94,14 +94,14 @@ function generateDefaultList() {
}
const show = ref(false);
const checkAll = computed(()=>{
const checkAll = computed(() => {
let baseNum = 0;
offList.value.map((v) => {
if (v.fix) {
baseNum += 1;
}
});
return onList.value.length == offList.value.length-baseNum
return onList.value.length == offList.value.length - baseNum;
});
function showModal() {
@ -274,11 +274,11 @@ const getData = async (type = "") => {
* fix 是否默认
* checked 是否选中
*/
const userFieldFixed = useList.userFieldFixed?.split(",");
const userFieldUnFixed = useList.userFieldUnFixed?.split(",");
const userFieldFixed = useList?.userFieldFixed?.split(",");
const userFieldUnFixed = useList?.userFieldUnFixed?.split(",");
if (!type || type == "off") {
offList.value = [];
allList.map((v) => {
allList?.map((v) => {
let item = {
name: v.fieldDesc,
id: v.name,
@ -297,7 +297,7 @@ const getData = async (type = "") => {
offList.value.unshift(...fixList.value);
}
if (!type || type == "on") {
useList.userFieldFixed?.split(",").map((v) => {
useList?.userFieldFixed?.split(",").map((v) => {
let item = allList.find((v2) => v2.name == v);
if (item) {
item = {
@ -327,7 +327,10 @@ const indeterminate = computed(() => {
baseNum += 1;
}
});
return onShowList.value.length > 0 && offShowList.value.length - baseNum > onShowList.value.length;
return (
onShowList.value.length > 0 &&
offShowList.value.length - baseNum > onShowList.value.length
);
});
const queryData = (value, type) => {
if (value) {
@ -433,7 +436,7 @@ const queryData = (value, type) => {
</template>
</n-input>
<div class="draggable-title">系统默认</div>
<div class="draggable-ul" style="border-bottom:none">
<div class="draggable-ul" style="border-bottom: none">
<div
v-for="item in fixShowList"
:key="item.id"

@ -0,0 +1,380 @@
<script lang="ts" setup>
import type { FormInst, FormItemRule, FormRules } from 'naive-ui'
import { computed, onBeforeMount, reactive, ref, unref, watch } from 'vue'
import { asideTaskMap as asideMap } from '@/config/final'
import { useDictionary } from '@/store/modules/dictonary'
import { useConfig } from '@/store/modules/asideConfig'
import type { FilterCondition } from '/#/api'
import { addCondition, updateCondition } from '@/api/home/filter'
import { formatToDate2, formatToDate3 } from '@/utils/dateUtil'
type Status = 'edit' | 'new'
const show = ref(false)
const configStore = useConfig()
const dicStore = useDictionary()
const currentStatus = ref<Status>('new')
let currentEditId: string | null = null
const modalTitle = computed(() => {
return currentStatus.value === 'new' ? '新建过滤条件' : '编辑过滤条件'
})
const cardStyle = {
'width': '800px',
'--n-padding-bottom': '10px',
'--n-padding-left': '10px',
}
const noBorderInput = {
'--n-border': '0px',
'--n-border-hover': '0px',
'--n-border-pressed': '0px',
}
const formItemStyle = {
'--n-label-height': '0px',
'--n-feedback-height': '8px',
}
interface FormType {
name: string | null
logic: string | null
conditions: Condition[]
}
interface Condition {
type: string | null
operator: string | null
result: any
}
interface Option {
label: string
value: string
}
const rules: FormRules = {
name: {
required: true,
message: '请输入过滤条件名称',
trigger: 'blur',
},
logic: {
required: true,
message: '请选择逻辑关系',
trigger: 'blur',
},
conditions: {
required: true,
validator(rule: FormItemRule, value: Condition[]) {
for (const item of value) {
const { type, operator, result } = item
if (type === null || operator === null || result === null)
return new Error('请选择过滤条件')
}
return true
},
trigger: ['input', 'blur'],
},
}
const formRef = ref<FormInst | null>(null)
const formValue = reactive<FormType>({
name: null,
logic: 'where',
conditions: [{
type: null,
operator: 'eq',
result: null,
}],
})
function handleSumbit(e: MouseEvent) {
e.preventDefault()
formRef.value?.validate((errors) => {
if (errors)
return
const list = formValue.conditions.map((item, index) => {
const { type, operator, result } = item
return {
searchfield: type!,
searchtype: operator!,
searchvalue: formatValue(type!, result),
searchRelationType: formValue.logic!,
orderNum: index + 1,
}
})
const param: FilterCondition = {
searchname: formValue.name!,
type: 1,
ocrUsersearchchildList: list,
}
if (currentStatus.value === 'new')
addCondition(param)
else
updateCondition({ id: currentEditId!, ...param })
closeModal()
})
}
function formatValue(searchfield: string, searchvalue: any) {
if (searchfield === 'izuptime') {
const start = formatToDate2(searchvalue[0])
const end = formatToDate2(searchvalue[1])
return `${start}-${end}`
}
return searchvalue
}
//
function unformatValue(searchfield: string, searchvalue: any) {
// 2022/01/03-2023/02/04
if (searchfield === 'izuptime') {
const dataStrs = searchvalue.split('-')
const start = formatToDate3(dataStrs[0])
const end = formatToDate3(dataStrs[1])
return [start, end]
}
return searchvalue
}
function createCondition() {
formValue.conditions.push({
type: null,
operator: 'eq',
result: null,
})
}
function removeCondition(index: number) {
formValue.conditions.splice(index, 1)
}
function formLabel(index: number) {
return index === 0 ? '筛选条件' : ''
}
const typeOptions = ref<Option[]>([])
const operatorOptions = [
{
label: '等于',
value: 'eq',
},
{
label: '不等于',
value: 'notEq',
},
]
const logicOptions = ref([])
onBeforeMount(() => {
dicStore.fetchRelationTypeList()
})
watch(() => dicStore.relationTypeList, (newval) => {
logicOptions.value = newval
})
function showModal() {
show.value = true
}
function closeModal() {
show.value = false
}
function generateAllData(): Option[] {
const initVal: Option[] = []
const list = Object.keys(asideMap).reduce((acc, value) => {
if (value.startsWith('iz') && asideMap[value]?.inFilterList !== false) {
const name = asideMap[value]?.label
name && acc.push({
value,
label: name || '未配置',
})
}
return acc
}, initVal)
return list
}
typeOptions.value = generateAllData()
function getOptions(key: string) {
const getterName = `get${key}`
const options = unref(dicStore[getterName])
return options || []
}
function leaveHandler() {
currentStatus.value = 'new'
currentEditId = null
formValue.name = null
formValue.conditions = [
{
type: null,
operator: 'eq',
result: null,
},
]
}
function edit(editFilter: any) {
currentStatus.value = 'edit'
const { searchname, ocrUsersearchchildList, id } = editFilter
currentEditId = id
formValue.name = searchname
formValue.conditions = ocrUsersearchchildList.map((item) => {
return {
type: item.searchfield,
operator: item.searchtype,
result: unformatValue(item.searchfield, item.searchvalue),
}
})
}
defineExpose({
showModal,
edit,
})
</script>
<template>
<n-modal v-model:show="show" transform-origin="center" @after-leave="leaveHandler">
<n-card :style="cardStyle" :bordered="false" size="huge" role="dialog" aria-modal="true">
<div class="wrapper">
<span class="wrapper-title">{{ modalTitle }}</span>
<div class="wrapper-bar">
<div class="wrapper-info">
<span :style="{ 'margin-left': '18px' }">基本信息</span>
</div>
</div>
<div class="wrapper-form">
<n-form ref="formRef" :model="formValue" :rules="rules">
<n-form-item path="name" label="标题">
<n-input v-model:value="formValue.name" :style="{ width: '780px' }" @keydown.enter.prevent />
</n-form-item>
<n-form-item path="logic" label="逻辑关系" v-show="false">
<n-select filterable v-model:value="formValue.logic" placeholder="请选择逻辑关系" :options="logicOptions" />
</n-form-item>
<n-form-item
v-for="(item, index) in formValue.conditions" :key="index" :style="formItemStyle"
path="conditions" :label="formLabel(index)"
>
<n-select filterable
v-model:value="item.type" placeholder="请选择筛选项名称" :options="typeOptions"
/>
<n-select filterable
v-model:value="item.operator" style="margin-left: 8px;" placeholder="请选择"
:options="operatorOptions"
/>
<n-space v-if="item.type === 'izuptime'">
<n-date-picker
v-model:value="item.result" style="margin-left: 8px;width: 240px;" type="daterange"
clearable
/>
</n-space>
<n-select filterable
v-else v-model:value="item.result" style="margin-left: 8px;" placeholder="请选择" :options="getOptions(item.type!)"
/>
<n-button :style="noBorderInput" icon-placement="right" @click="removeCondition(index)">
<template #icon>
<SvgIcon size="24" name="close" />
</template>
</n-button>
</n-form-item>
</n-form>
</div>
<div class="wrapper-new" @click="createCondition">
<span>+</span>
<span style="margin-left:8px">添加筛选条件</span>
</div>
</div>
<template #footer>
<div class="wrapper-footer">
<n-button type="info" @click="handleSumbit">
保存
</n-button>
<n-button secondary style="margin-left:15px" @click="closeModal">
取消
</n-button>
</div>
</template>
</n-card>
</n-modal>
</template>
<style lang="less" scoped>
.wrapper {
display: flex;
flex-direction: column;
&-title {
font-weight: bold;
font-size: 16px;
}
&-bar {
background-color: #e8e8e8;
width: 100%;
margin-top: 20px;
}
&-form {
display: flex;
justify-content: space-between;
margin-top: 20px;
}
&-new {
display: flex;
width: 110px;
color: #507afd;
line-height: 22px;
cursor: pointer;
&:hover {
color: #507aac;
}
}
&-table {
margin-top: 20px;
}
&-footer {
display: flex;
justify-content: flex-end;
}
&-info {
font-weight: bold;
position: relative;
&:before {
background-color: #1980FF;
content: "";
width: 5px;
border-radius: 2px;
top: 0;
bottom: 0;
position: absolute;
}
}
}
</style>

@ -36,7 +36,7 @@ const popconfirmTarget: any = ref(null)
const popconfirmRef: any = ref(null)
function handleDismissTask() {
emit('dismisClick', props.mouseOverTask.id)
emit('dismisClick', props.mouseOverTask.id)
popconfirmRef.value[0]?.setShow(false); // popconfirm
}
@ -69,21 +69,21 @@ onMounted(async () => {
</div>
<ul v-else class="list-item-detail">
<li v-if="item.id === 'statshisText'">
审批状态<span class="list-item-status" :class="listItem.statshisText === ''
审批状态<n-ellipsis style="max-width: 170px"><span class="list-item-status" :class="listItem.statshisText === ''
? 'list-item-success'
: listItem.statshisText === '不通过'
? 'list-item-error'
: 'list-item-watting'
">{{ listItem.statshisText }}</span>
</li>
</n-ellipsis></li>
<li v-else-if="item.id === 'createdate'">
提交时间{{ format(listItem.createdate, "yyyy-MM-dd HH:mm:ss") }}
提交时间<n-ellipsis style="max-width: 170px">{{ listItem.createdate && format(listItem.createdate, "yyyy-MM-dd HH:mm:ss") }}</n-ellipsis>
</li>
<li v-else-if="item.id === 'createTime'">
生成时间{{ listItem.createTime && format(listItem.createTime, "yyyy-MM-dd HH:mm:ss") }}
生成时间<n-ellipsis style="max-width: 170px">{{ listItem.createTime && format(listItem.createTime, "yyyy-MM-dd HH:mm:ss") }}</n-ellipsis>
</li>
<li v-else class="ellipsis" v-if="listItem[item.id]">
<span class="label">{{ item.name }}</span>{{ listItem[item.id] }}
<li v-else class="ellipsis">
<span class="label">{{ item.name }}</span><n-ellipsis style="max-width: 170px">{{ listItem[item.id] }}</n-ellipsis>
</li>
</ul>
</div>
@ -185,6 +185,5 @@ onMounted(async () => {
position: absolute;
bottom: 0px;
}
}
</style>
}</style>
../types

Loading…
Cancel
Save