refactor: 调整审批

bak
elseif 2 years ago
parent 35acdd97cd
commit ec4bd86324

@ -15,7 +15,7 @@
},
"dependencies": {
"@vueup/vue-quill": "^1.2.0",
"@vueuse/core": "^10.7.0",
"@vueuse/core": "10.9.0",
"axios": "^1.4.0",
"date-fns": "^2.30.0",
"esno": "^0.16.3",

@ -9,8 +9,8 @@ dependencies:
specifier: ^1.2.0
version: 1.2.0(vue@3.3.10)
'@vueuse/core':
specifier: ^10.7.0
version: 10.7.0(vue@3.3.10)
specifier: 10.9.0
version: 10.9.0(vue@3.3.10)
axios:
specifier: ^1.4.0
version: 1.6.2
@ -1640,26 +1640,26 @@ packages:
vue: 3.3.10(typescript@4.9.5)
dev: false
/@vueuse/core@10.7.0(vue@3.3.10):
resolution: {integrity: sha512-4EUDESCHtwu44ZWK3Gc/hZUVhVo/ysvdtwocB5vcauSV4B7NiGY5972WnsojB3vRNdxvAt7kzJWE2h9h7C9d5w==}
/@vueuse/core@10.9.0(vue@3.3.10):
resolution: {integrity: sha512-/1vjTol8SXnx6xewDEKfS0Ra//ncg4Hb0DaZiwKf7drgfMsKFExQ+FnnENcN6efPen+1kIzhLQoGSy0eDUVOMg==}
dependencies:
'@types/web-bluetooth': 0.0.20
'@vueuse/metadata': 10.7.0
'@vueuse/shared': 10.7.0(vue@3.3.10)
vue-demi: 0.14.6(vue@3.3.10)
'@vueuse/metadata': 10.9.0
'@vueuse/shared': 10.9.0(vue@3.3.10)
vue-demi: 0.14.7(vue@3.3.10)
transitivePeerDependencies:
- '@vue/composition-api'
- vue
dev: false
/@vueuse/metadata@10.7.0:
resolution: {integrity: sha512-GlaH7tKP2iBCZ3bHNZ6b0cl9g0CJK8lttkBNUX156gWvNYhTKEtbweWLm9rxCPIiwzYcr/5xML6T8ZUEt+DkvA==}
/@vueuse/metadata@10.9.0:
resolution: {integrity: sha512-iddNbg3yZM0X7qFY2sAotomgdHK7YJ6sKUvQqbvwnf7TmaVPxS4EJydcNsVejNdS8iWCtDk+fYXr7E32nyTnGA==}
dev: false
/@vueuse/shared@10.7.0(vue@3.3.10):
resolution: {integrity: sha512-kc00uV6CiaTdc3i1CDC4a3lBxzaBE9AgYNtFN87B5OOscqeWElj/uza8qVDmk7/U8JbqoONLbtqiLJ5LGRuqlw==}
/@vueuse/shared@10.9.0(vue@3.3.10):
resolution: {integrity: sha512-Uud2IWncmAfJvRaFYzv5OHDli+FbOzxiVEQdLCKQKLyhz94PIyFC3CHcH7EDMwIn8NPtD06+PNbC/PiO0LGLtw==}
dependencies:
vue-demi: 0.14.6(vue@3.3.10)
vue-demi: 0.14.7(vue@3.3.10)
transitivePeerDependencies:
- '@vue/composition-api'
- vue
@ -7116,6 +7116,21 @@ packages:
vue: 3.3.10(typescript@4.9.5)
dev: false
/vue-demi@0.14.7(vue@3.3.10):
resolution: {integrity: sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==}
engines: {node: '>=12'}
hasBin: true
requiresBuild: true
peerDependencies:
'@vue/composition-api': ^1.0.0-rc.1
vue: ^3.0.0-0 || ^2.6.0
peerDependenciesMeta:
'@vue/composition-api':
optional: true
dependencies:
vue: 3.3.10(typescript@4.9.5)
dev: false
/vue-draggable-plus@0.3.5(@types/sortablejs@1.15.7):
resolution: {integrity: sha512-HqIxV4Wr4U5LRPLRi2oV+EJ4g6ibyRKhuaiH4ZQo+LxK4zrk2XcBk9UyXC88OXp4SAq0XYH4Wco/T3LX5kJ79A==}
peerDependencies:

@ -7,16 +7,16 @@ import { ContentTypeEnum } from '@/enums/httpEnum'
*
* @returns
*/
export async function getApprovalList(page: PageParam, assigneeId: string) {
export async function getApprovalList(page: PageParam) {
const res = await http.request({
url: `/flow/task/listalldata`,
method: 'get',
params: { pageSize: page.pageSize, currPage: page.pageNo, assigneeId },
params: { pageSize: page.pageSize, currPage: page.pageNo },
})
const { data: { list, totalPage } } = res
const { data: { list, totalCount } } = res
return {
pageCount: totalPage,
pageCount: Math.ceil(totalCount / page.pageSize!),
data: list,
}
}

@ -28,8 +28,10 @@ export async function getPackageList(params: PageParam, packagename: string) {
* @returns
*/
export async function getPackageTaskList(packageid: string, params: PageParam) {
const pid = packageid || 0
const res = await http.request({
url: `/backstage/jifen/ocrtaskchildpicture/listbypackageid/${packageid}`,
url: `/backstage/jifen/ocrtaskchildpicture/listbypackageid/${pid}`,
method: 'get',
params,
})
@ -48,8 +50,10 @@ export async function getPackageTaskList(packageid: string, params: PageParam) {
* @returns
*/
export async function getTaskDetailInfo(taskId: string, packageid: string) {
const pid = packageid || 0
const res = await http.request({
url: `/backstage/jifen/ocrtaskchildpicture/getdata/${taskId}/${packageid}`,
url: `/backstage/jifen/ocrtaskchildpicture/getdata/${taskId}/${pid}`,
method: 'get',
})
@ -64,8 +68,10 @@ export async function getTaskDetailInfo(taskId: string, packageid: string) {
* @returns
*/
export async function getTaskDetailPictureList(packageid: string, taskchildpictureid: string, params: PageParam & PictureSortParam) {
const pid = packageid || 0
const res = await http.request({
url: `/backstage/jifen/ocrtaskchildpicture/listbypictureid/${packageid}/${taskchildpictureid}`,
url: `/backstage/jifen/ocrtaskchildpicture/listbypictureid/${pid}/${taskchildpictureid}`,
method: 'get',
params,
})

@ -18,7 +18,7 @@ export interface DictionaryState {
izCustomtypeList: any
izcustomnameList: any
izcustomlevelList: any
izizprojecttypeList: any
izprojecttypeList: any
izvisitcityList: any
rejectList: any
backList: any
@ -44,7 +44,7 @@ export const useDictionaryStore = defineStore({
izcustomnameList: null,
izCustomtypeList: null,
izcustomlevelList: null,
izizprojecttypeList: null,
izprojecttypeList: null,
izvisitcityList: null,
rejectList: null,
backList: null,
@ -94,8 +94,11 @@ export const useDictionaryStore = defineStore({
getizcustomlevel: (state) => {
return state.izcustomlevelList
},
getizizprojecttype: (state) => {
return state.izizprojecttypeList
getizprojecttype: (state) => {
return state.izprojecttypeList
},
getizstatus: (state) => {
return state.izstatusList
},
},
actions: {
@ -195,8 +198,8 @@ export const useDictionaryStore = defineStore({
// 项目类别
async fetchizizprojecttypeList() {
const list = await getBusinessList('izprojecttype')
this.izizprojecttypeList = list
return this.izizprojecttypeList
this.izprojecttypeList = list
return this.izprojecttypeList
},
// 发布地区
async fetchizvisitcityList() {

@ -10,7 +10,6 @@ export const useTaskStore = defineStore({
activeId: '',
approvalList: [],
packageid: '',
refresh: false,
immersion: false,
}),
getters: {
@ -26,7 +25,7 @@ export const useTaskStore = defineStore({
setActive(index: number, taskId?: string) {
this.currentIndex = index
const task = this.approvalList[index]
this.activeId = taskId || task?.formid
this.activeId = taskId || task?.id
this.packageid = task.packageid
},
forward() {
@ -43,14 +42,12 @@ export const useTaskStore = defineStore({
this.setActive(--this.currentIndex)
},
async fetchApprovalList(pagination, id, refresh?: boolean) {
const res = await getApprovalList(pagination, id)
async fetchApprovalList(pagination) {
const res = await getApprovalList(pagination)
if (res.data.length > 0) {
this.setApprovalList(res.data)
this.approvalList.push(...res.data)
if (!this.activeId)
this.setActive(0)
// 审批操作完成后需要刷新为防止activeId在刷新后值不变通过此值刷新
this.refresh = !this.refresh
}
return res

@ -1,4 +1,4 @@
import { format } from 'date-fns'
import { format, parse } from 'date-fns'
const DATE_TIME_FORMAT = 'YYYY-MM-DD HH:mm'
const DATE_FORMAT = 'YYYY-MM-DD '
@ -20,3 +20,9 @@ export function formatToDate2(date: Date | number, formatStr = DATA_FORMAT_2): s
export function formatToDateHMS(date: Date | number, formatStr = DATE_FORMAT_HMS) {
return format(date, formatStr)
}
// 将yyyy/mm/dd转换为时间戳
export function formatToDate3(dateString: string) {
const dateObject = parse(dateString, 'yyyy/MM/dd', new Date())
return dateObject.getTime()
}

@ -275,3 +275,12 @@ export function arrayEquals(a, b) {
export function notEmpty(value: any) {
return !(value === undefined || value === '' || value === null || (Array.isArray(value) && value.length === 0))
}
/**
*
* @param value
* @returns
*/
export function isEmpty(value: any) {
return (value === undefined || value === '' || value === null)
}

@ -1,6 +1,6 @@
<script lang="ts" setup>
import { computed, nextTick, onBeforeMount, onMounted, reactive, ref, shallowRef, unref, watch } from 'vue'
import { CustomFilterModalVue } from '@/views/final/comp'
import { CustomFilterModalVue, FilterModal, NewFilterModal } from '@/views/final/comp'
import Search from '@/views/home/aside/comp/Search.vue'
import AdvanceFilter from '@/views/home/aside/comp/AdvanceFilter.vue'
import { getViewportOffset } from '@/utils/domUtils'
@ -169,7 +169,7 @@ watch(asideValue, (newVal) => {
<Search v-show="showSearch" @select="scrollHandler" @close="setShowSearch(false)" />
<!-- 高级筛选 -->
<AdvanceFilter
v-show="!showSearch" @select="filterHandler" @update:search="setShowSearch(true)"
v-show="!showSearch" :type="1" @select="filterHandler" @update:search="setShowSearch(true)"
@show-custom="showModal(customModalRef)" @show-filter="showModal(filterModalRef)"
/>
</div>
@ -181,6 +181,10 @@ watch(asideValue, (newVal) => {
<!-- 筛选 -->
<CustomFilterModalVue ref="customModalRef" />
<!-- 过滤列表 -->
<FilterModal ref="filterModalRef" @edit-filter="editFilter" @show-new-filter="showModal(newFilterModalRef)" />
<!-- 新增过滤 -->
<NewFilterModal ref="newFilterModalRef" />
</n-scrollbar>
</div>
</template>

@ -0,0 +1,347 @@
<script lang="ts" setup>
import { defineOptions, h, nextTick, onUnmounted, reactive, ref, unref } from 'vue'
import { NDataTable } from 'naive-ui'
import type { DataTableColumns, DataTableRowKey } from 'naive-ui'
import type { SortableEvent } from 'sortablejs'
import Sortable from 'sortablejs'
import { debounce } from 'lodash-es'
import Action from '@/views/home/aside/comp/Action.vue'
import { deleteCondition, getConditionList, sort } from '@/api/home/filter'
import type { FilterSearchParam } from '/#/api'
defineOptions({ name: 'FilterModal' })
const emit = defineEmits<{
(e: 'showNewFilter'): void
(e: 'editFilter', filter: any): void
}>()
const show = ref(false)
const cardStyle = {
'width': '800px',
'height': '800px',
'--n-padding-bottom': '10px',
'--n-padding-left': '10px',
}
interface RowData {
id: string
searchname: string
createby: string
createtime: string
updateby: string
updatetime: string
}
const columns: DataTableColumns<RowData> = [
{
type: 'selection',
},
{
title: '操作',
key: 'action',
render(row) {
return h(
Action,
{
options: [
{ label: '编辑', key: 1 },
{ label: '删除', key: 2 },
],
id: row.id,
select,
},
)
},
},
{
title: '名称',
key: 'searchname',
},
{
title: '创建者',
key: 'createby',
},
{
title: '创建时间',
key: 'createtime',
},
{
title: '更新者',
key: 'updateby',
},
{
title: '更新时间',
key: 'updatetime',
},
]
const loading = ref(true)
const pagination = reactive({
page: 1,
pageCount: 1,
pageSize: 10,
})
const tableData = ref<Array<RowData>>([])
const keyword = ref('')
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, 1)
const { data, pageCount } = result
tableData.value = data
pagination.page = page
pagination.pageCount = pageCount
loading.value = false
}
function afterLeave() {
pagination.page = 1
pagination.pageCount = 1
pagination.pageSize = 10
}
const selectionIds = ref<DataTableRowKey[]>([])
const rowKey = (row: RowData) => row.id
function rowProps(row: RowData) {
return {
'data-id': row.id,
}
}
function handleCheck(rowKeys: DataTableRowKey[]) {
selectionIds.value = rowKeys
}
function select(key: number) {
switch (key) {
case 1:
editSelection()
break
case 2:
deleteSelection()
break
default:
break
}
}
function editSelection() {
// eslint-disable-next-line dot-notation
const $message = window['$message']
if (selectionIds.value.length === 0 || selectionIds.value.length > 1) {
$message.error('请选中一条过滤')
return
}
const selectedId = selectionIds.value[0]
const selectedFilter = tableData.value.find((item: any) => {
return item.id === selectedId
})
emit('editFilter', selectedFilter)
closeModal()
}
function deleteSelection() {
// eslint-disable-next-line dot-notation
const $message = window['$message']
if (selectionIds.value.length === 0) {
$message.error('至少选中一条过滤')
return
}
deleteCondition({ ids: selectionIds.value.join(',') }).then(() => {
query(pagination.page, pagination.pageSize)
})
}
async function handlePageChange(currentPage) {
if (loading.value)
return
const { pageSize } = pagination
await query(currentPage, pageSize)
}
function handleClick() {
emit('showNewFilter')
show.value = false
}
let sortTable: Sortable | null = null
const tableRef = ref<InstanceType<typeof NDataTable>>()
async function showModal() {
show.value = true
const { page, pageSize } = pagination
await query(page, pageSize)
nextTick(() => {
if (sortTable !== null)
destory()
const el: HTMLDivElement = tableRef.value?.$el
const tbody: HTMLElement | null = el.querySelector('tbody.n-data-table-tbody')!
if (tbody)
sortTable = Sortable.create(tbody, { onEnd, onMove })
})
}
let relatedId = ''
let insertafter = false
// TODO: bug
function onEnd(event: SortableEvent) {
const data = unref(tableData)
const oldElem = data[event.oldIndex!]
data.splice(event.oldIndex!, 1)
data.splice(event.newIndex!, 0, oldElem)
const dragId = oldElem.id
const index = data.findIndex((item) => {
return item.id === relatedId
})
// -1+1
const order = insertafter ? index - 1 : index + 1
// console.log('dragid:', dragId, 'order:', order)
sort(dragId, order)
}
function onMove(evt: any) {
relatedId = evt.related?.dataset?.id
insertafter = evt.willInsertAfter
// console.log(`${evt.dragged.dataset.id},${evt.related}`, 'insertafter', evt.willInsertAfter)
}
function destory() {
sortTable && sortTable.destroy()
sortTable = null
}
onUnmounted(() => {
destory()
})
function closeModal() {
show.value = false
}
defineExpose({
showModal,
})
const inputHandler = debounce((word) => {
keyword.value = word
query(1, 5)
}, 300)
</script>
<template>
<div>
<n-modal
v-model:show="show" transform-origin="center" display-directive="if"
@after-leave="afterLeave"
>
<n-card :style="cardStyle" :bordered="false" size="huge" role="dialog" aria-modal="true">
<div class="wrapper">
<span class="wrapper-title">全部筛选值</span>
<div class="wrapper-bar">
<div class="wrapper-info">
<span :style="{ 'margin-left': '18px' }">基本信息</span>
</div>
</div>
<div class="wrapper-form">
<n-input :style="{ width: '360px', border: '1px solid #cad2dd' }" placeholder="请输入过滤条件名称搜索" @input="inputHandler">
<template #suffix>
<SvgIcon size="14px" name="magnifying-1" />
</template>
</n-input>
<n-button type="info" @click="handleClick">
创建
<template #icon>
<SvgIcon size="14px" name="magnifying-1" />
</template>
</n-button>
</div>
<div class="wrapper-table">
<NDataTable
ref="tableRef" remote :row-props="rowProps as any" :columns="columns" :data="tableData" :loading="loading"
:pagination="pagination" :row-key="rowKey" @update:page="handlePageChange"
@update:checked-row-keys="handleCheck"
/>
</div>
</div>
<template #footer>
<div class="wrapper-footer">
<n-button type="info" @click="closeModal">
确认
</n-button>
<n-button secondary style="margin-left:15px" @click="closeModal">
取消
</n-button>
</div>
</template>
</n-card>
</n-modal>
</div>
</template>
<style lang="less" scoped>
.wrapper {
display: flex;
flex-direction: column;
&-title {
font-weight: bold;
font-size: 16px;
}
&-bar {
background-color: #f8f8f8;
width: 100%;
margin-top: 20px;
}
&-form {
display: flex;
justify-content: space-between;
margin-top: 20px;
.n-input {
width: 300px;
border: 1px solid gray
}
}
&-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>

@ -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 { 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: null,
conditions: [{
type: null,
operator: null,
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: null,
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: null,
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="逻辑关系">
<n-select 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
v-model:value="item.type" placeholder="请选择筛选项名称" :options="typeOptions"
/>
<n-select
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
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>

@ -5,5 +5,7 @@ import RepeatTaskTableModal from './RepeatTaskTableModal.vue'
import Action from './Action.vue'
import RejectModal from './RejectModal.vue'
import CustomFilterModalVue from './CustomFilterModalVue.vue'
import FilterModal from './FilterModal.vue'
import NewFilterModal from './NewFilterModal.vue'
export { CustomTabelModal, ImportExcelModal, RepeatModal, RepeatTaskTableModal, Action, RejectModal, CustomFilterModalVue }
export { CustomTabelModal, ImportExcelModal, RepeatModal, RepeatTaskTableModal, Action, RejectModal, CustomFilterModalVue, FilterModal, NewFilterModal }

@ -82,7 +82,7 @@ configStore.$subscribe(() => {
const config = configStore.getConfig
const customConfig = configStore.getCustomConfig
if (config === null || customConfig === null)
if (config == null || customConfig == null)
return
const showKeys = [...customConfig].filter(key => !asideMap[key].isDefaultFilter)
@ -168,7 +168,7 @@ watch(asideValue, (newVal) => {
<Search v-show="showSearch" @select="scrollHandler" @close="setShowSearch(false)" />
<!-- 高级筛选 -->
<AdvanceFilter
v-show="!showSearch" @select="filterHandler" @update:search="setShowSearch(true)"
v-show="!showSearch" :type="0" @select="filterHandler" @update:search="setShowSearch(true)"
@show-custom="showModal(customModalRef)" @show-filter="showModal(filterModalRef)"
/>
</div>

@ -9,6 +9,14 @@ import type { FilterSearchParam } from '/#/api'
defineOptions({ name: 'AdvanceFilter' })
const props = defineProps({
type: {
type: Number,
default: 0,
required: true,
},
})
const emit = defineEmits<{
(e: 'show-filter'): void
(e: 'show-custom'): void
@ -78,7 +86,7 @@ async function featchList() {
loading = true
try {
const searchParam: FilterSearchParam = { search_searchname: { value: keyword.value, op: 'like', type: 'string' } }
const result = await getConditionList(pagination, searchParam, 0)
const result = await getConditionList(pagination, searchParam, props.type)
const { data } = result
// pagination.pageNo += 1
// canloadMore = pageCount >= pagination.pageNo

@ -23,6 +23,10 @@ const inputHandler = debounce((keyword) => {
configStore.$subscribe(() => {
const customConfig = configStore.getCustomConfig
if (customConfig == null)
return
const keys = customConfig ? [...customConfig] : []
if (keys.length === 0)

@ -113,7 +113,7 @@ configStore.$subscribe(() => {
const config = configStore.getConfig
const customConfig = configStore.getCustomConfig
if (config === null || customConfig === null)
if (config == null || customConfig == null)
return
const { showList, hideList } = generatList(config, customConfig)

@ -6,9 +6,7 @@ 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 } from '@/utils/dateUtil'
defineOptions({ name: 'NewFilterModal' })
import { formatToDate2, formatToDate3 } from '@/utils/dateUtil'
type Status = 'edit' | 'new'
@ -96,7 +94,6 @@ const formValue = reactive<FormType>({
function handleSumbit(e: MouseEvent) {
e.preventDefault()
const v = formRef.value
formRef.value?.validate((errors) => {
if (errors)
return
@ -127,6 +124,7 @@ function handleSumbit(e: MouseEvent) {
})
}
//
function formatValue(searchfield: string, searchvalue: any) {
if (searchfield === 'izyear') {
const start = formatToDate2(searchvalue[0])
@ -134,12 +132,29 @@ function formatValue(searchfield: string, searchvalue: any) {
return `${start}-${end}`
}
if (Array.isArray(searchvalue))
if (searchfield === 'izsimilarity' && Array.isArray(searchvalue))
return searchvalue.join(',')
return searchvalue
}
//
function unformatValue(searchfield: string, searchvalue: any) {
// 2022/01/03-2023/02/04
if (searchfield === 'izyear') {
const dataStrs = searchvalue.split('-')
const start = formatToDate3(dataStrs[0])
const end = formatToDate3(dataStrs[1])
return [start, end]
}
// 80,90
if (searchfield === 'izsimilarity')
return searchvalue.split(',')
return searchvalue
}
function createCondition() {
formValue.conditions.push({
type: null,
@ -194,8 +209,6 @@ watch(() => dicStore.relationTypeList, (newval) => {
logicOptions.value = newval
})
const resultOptions = ref<Option[]>([])
function showModal() {
show.value = true
}
@ -206,6 +219,7 @@ function closeModal() {
function generateAllData(config): Option[] {
const initVal: Option[] = []
const list = Object.keys(config).reduce((acc, value) => {
if (value.startsWith('iz') && asideMap[value]?.inFilterList !== false) {
const name = asideMap[value]?.label
@ -222,19 +236,20 @@ function generateAllData(config): Option[] {
}
watch(() => configStore.systemConfig, (newVal) => {
if (!newVal)
return
const list = generateAllData(newVal)
typeOptions.value = list
})
function handleTypeUpate(value: string) {
if (value === 'izsimilarity') {
resultOptions.value = similarityOptions as any
return
}
function getOptions(key: string) {
if (key === 'izsimilarity')
return similarityOptions
const key = `get${value}`
const options = unref(dicStore[key])
resultOptions.value = options || []
const getterName = `get${key}`
const options = unref(dicStore[getterName])
return options || []
}
function leaveHandler() {
@ -261,7 +276,7 @@ function edit(editFilter: any) {
return {
type: item.searchfield,
operator: item.searchtype,
result: item.searchvalue,
result: unformatValue(item.searchfield, item.searchvalue),
}
})
}
@ -296,7 +311,6 @@ defineExpose({
>
<n-select
v-model:value="item.type" placeholder="请选择筛选项名称" :options="typeOptions"
@update:value="handleTypeUpate"
/>
<n-select
v-model:value="item.operator" style="margin-left: 8px;" placeholder="请选择"
@ -309,7 +323,7 @@ defineExpose({
/>
</n-space>
<n-select
v-else v-model:value="item.result" style="margin-left: 8px;" placeholder="请选择" :options="resultOptions"
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>

@ -35,9 +35,9 @@ const show = ref(false)
const flag = ref(true)
const formInline: FormState = reactive({
enterprisecode: '三方系统标识8',
username: '13311111111',
password: '12345678l',
enterprisecode: '演示公司',
username: 'yanshi01',
password: '123456',
})
const formSms: FormSms = reactive({

@ -84,7 +84,7 @@ const inputHandler = debounce((word) => {
<SvgIcon size="16px" style="margin-left: 6px;cursor: pointer;" name="clear" @click="setShowSearch(false)" />
</div>
</div>
<TaskList ref="taskListRef" style="height: calc(100vh - 146px);" class="work-sheet-list" />
<TaskList ref="taskListRef" class="work-sheet-list" />
<CustomFieldModal ref="CustomFieldModalRef" />
</div>
</template>

@ -3,7 +3,6 @@ import { onMounted, onUnmounted, reactive, ref, watch } from 'vue'
import { useInfiniteScroll } from '@vueuse/core'
import ListItem from './ListItem.vue'
import { useTaskStore } from '@/store/modules/task'
import { useUser } from '@/store/modules/user'
import emitter from '@/utils/mitt'
defineOptions({ name: 'WorkSheetList' })
@ -14,11 +13,10 @@ const activeId = ref('')
const el = ref<HTMLDivElement | null>(null)
const keyword = ref('')
const canloadMore = ref(true)
const userStore = useUser()
const pagination = reactive({
pageNo: 0,
pageSize: 10,
pageSize: 30,
})
function selectHandler(id: string, index: number) {
@ -30,10 +28,7 @@ const { isLoading } = useInfiniteScroll(
() => {
loadMore()
},
{ distance: 10, interval: 300, canLoadMore: () => {
// console.log('canloadmore excuted!')
return canloadMore.value
} },
{ distance: 10, interval: 300, canLoadMore: () => canloadMore.value },
)
async function loadMore() {
@ -47,10 +42,9 @@ async function loadMore() {
async function fetchList() {
try {
pagination.pageNo += 1
const id = userStore.getUserInfo.id
const result = await taskStore.fetchApprovalList(pagination, id)
const result = await taskStore.fetchApprovalList(pagination)
const { data, pageCount } = result
canloadMore.value = pageCount >= pagination.pageNo && pageCount !== 0
canloadMore.value = pageCount >= pagination.pageNo
return data || []
}
catch (error) {
@ -65,9 +59,11 @@ watch(() => taskStore.activeId, (newVal) => {
function reset() {
pagination.pageNo = 0
pagination.pageSize = 10
pagination.pageSize = 30
canloadMore.value = true
data.value.length = 0
taskStore.reset()
}
async function search(word: string) {
@ -91,7 +87,6 @@ onUnmounted(() => {
})
async function refreshHandler() {
reset()
search('')
}
@ -101,17 +96,29 @@ defineExpose({
</script>
<template>
<n-scrollbar>
<n-spin :show="isLoading">
<div ref="el">
<div ref="el" class="list">
<ListItem
v-for="(item, index) in data" :key="item.id" :selected="activeId === item.formid" :list-item="item"
v-for="(item, index) in data" :key="item.id" :selected="activeId === item.id" :list-item="item"
@click="selectHandler(item.id, index)"
/>
</div>
</n-spin>
</n-scrollbar>
</template>
<style lang="less" scoped>
.list {
height: calc(100vh - 146px);
overflow-y: scroll;
overflow-x: hidden;
scrollbar-width: none;
/* firefox */
-ms-overflow-style: none;
/* IE 10+ */
&::-webkit-scrollbar {
display: none;
}
}
</style>

@ -1,14 +1,15 @@
<script lang="ts" setup>
import { clone } from 'lodash-es'
import { useDialog, useMessage } from 'naive-ui'
import { computed, onUnmounted, reactive, ref, unref, watch } from 'vue'
import { isEmpty } from '@/utils'
import BatchModal from '../modal/BatchModal.vue'
import { audit } from '@/api/task/task'
import { getTaskDetailInfo, getTaskDetailPictureList } from '@/api/work/work'
import { useTask } from '@/store/modules/task'
import { useUser } from '@/store/modules/user'
import { hideDownload } from '@/utils/image'
import emitter from '@/utils/mitt'
import { clone } from 'lodash-es'
import { useDialog, useMessage } from 'naive-ui'
import { computed, onUnmounted, reactive, ref, unref, watch } from 'vue'
import BatchModal from '../modal/BatchModal.vue'
import ConfrimModal from '../modal/ConfrimModal.vue'
import CustomSettingModal from '../modal/CustomSettingModal.vue'
import PictureTable from './PictureTable.vue'
@ -192,18 +193,24 @@ function backHandler() {
taskStore.back()
}
watch(() => [taskStore.activeId, taskStore.refresh], async (newValue, oldValue) => {
watch(() => [taskStore.activeId], async (newValue, oldValue) => {
const packageid = taskStore.getPackageid
const taskId = taskStore.getActiveId
if (taskId === '' || packageid === '')
if (isEmpty(taskId))
return
taskDetailInfo.value = await getTaskDetailInfo(taskId, packageid)
if (!isEmpty(packageid)) {
const { data, total } = await getTaskDetailPictureList(packageid, taskId, { ...taskpagination, ...sortBy })
taskDetailPictureList.value = data
totalCount.value = total
}
else {
taskDetailPictureList.value.length = 0
totalCount.value = 0
}
})
const currentTaskId = computed(() => {

@ -295,12 +295,16 @@ function getSelectItems() {
async function refreshHandler() {
const packageid = taskStore.getPackageid
const taskId = taskStore.getActiveId
taskDetailInfo.value = await getTaskDetailInfo(taskId, packageid)
pagination.pageNo = 1
pagination.pageSize = 30
listData.value.length = 0
if (!packageid || !taskId)
return
const list = await featchList()
listData.value = list
layout()

1
types/task.d.ts vendored

@ -10,7 +10,6 @@ export interface TaskState {
packageid: string
currentIndex: number
approvalList: any[]
refresh: boolean
immersion: boolean
}

Loading…
Cancel
Save