Merge branch 'main' into shen

bak
Dragon 1 year ago
commit 35acdd97cd

@ -1,5 +1,5 @@
import { http } from '@/utils/http/axios' import { http } from '@/utils/http/axios'
import type { PageParam } from '/#/api' import type { BusinessParam, PageParam } from '/#/api'
/** /**
* *
@ -315,3 +315,69 @@ export async function getBackList() {
const list = res.data const list = res.data
return list return list
} }
/**
*
* @returns
*/
export async function getBusinessList(field: string, page: PageParam = { pageNo: 1, pageSize: 200 }) {
const res = await http.request({
url: `/ocr/dictionary/getDictionaryByField`,
method: 'get',
params: { ...page, field },
})
const { otherMessage: { records } } = res
return records.map((record) => {
return {
label: record.lable || 'todo',
value: record.value || 'todo',
}
})
}
/**
*
* @returns
*/
export async function getSystemList(code: string) {
const res = await http.request({
url: `/static/admin/web/distionary/bytypecode`,
method: 'get',
params: { code },
})
const { otherMessage: { records } } = res
return records.map((record) => {
return {
label: record.lable || 'todo',
value: record.value || 'todo',
}
})
}
/**
*
* @returns
*/
export async function getRelationTypeList() {
const res = await http.request({
url: `/static/admin/web/distionary/bytypecode/searchRelationType`,
method: 'get',
})
return res.data[0].distionaryList
}
/**
*
* @returns
*/
export async function getizstatusList() {
const res = await http.request({
url: `/static/admin/web/distionary/bytypecode/izstatus`,
method: 'get',
})
return res.data[0].distionaryList
}

@ -6,13 +6,14 @@ import type { FilterCondition, FilterParam, FilterSearchParam, FilterUpdate, Pag
* @param params * @param params
* @returns 1 * @returns 1
*/ */
export async function getConditionList(params: PageParam, searchParam: FilterSearchParam): Promise<any> { export async function getConditionList(page: PageParam, searchParam: FilterSearchParam, type: number): Promise<any> {
const res = await http.request({ const res = await http.request({
url: `/ocr/ocrUsersearch/list?`, url: `/ocr/ocrUsersearch/list?`,
method: 'get', method: 'get',
params: { params: {
...params, ...page,
search_searchname: JSON.stringify(searchParam.search_searchname), search_searchname: JSON.stringify(searchParam.search_searchname),
type,
}, },
}) })
@ -56,7 +57,7 @@ export async function updateCondition(params: FilterUpdate) {
export async function deleteCondition(params: { ids: string }) { export async function deleteCondition(params: { ids: string }) {
return http.request({ return http.request({
url: `/ocr/ocrUsersearch/deleteBatch`, url: `/ocr/ocrUsersearch/deleteBatch`,
method: 'delete', method: 'get',
params, params,
}) })
} }
@ -65,10 +66,11 @@ export async function deleteCondition(params: { ids: string }) {
* *
* @returns * @returns
*/ */
export async function getFilter(): Promise<any> { export async function getFilter(type: number): Promise<any> {
return http.request({ return http.request({
url: `/ocr/ocrSearchmanager/query`, url: `/ocr/ocrSearchmanager/query`,
method: 'get', method: 'get',
params: { type },
}) })
} }

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

@ -0,0 +1,52 @@
export const asideMap: Recordable<AsideEntity> = {
izupuser: {
label: '',
defaultValue: null,
isDefaultFilter: true,
key: 'izupuser',
component: ReportUserVue,
},
izproject: {
label: '',
defaultValue: null,
isDefaultFilter: true,
key: 'izproject',
component: IzProjectVue,
},
izplan: {
label: '',
defaultValue: null,
isDefaultFilter: true,
key: 'izplan',
component: PlanVue,
},
izstatus: {
label: '',
defaultValue: null,
isDefaultFilter: false,
key: 'izstatus',
component: PlanVue, // todo
},
izuptime: {
label: '',
defaultValue: null,
isDefaultFilter: false,
key: 'izuptime',
component: TimeVue,
},
iztaskrrom: {
label: '',
defaultValue: null,
isDefaultFilter: false,
key: 'iztaskrrom',
component: IztaskrromVue,
},
izshowall: {
label: '',
defaultValue: true,
isDefaultFilter: false,
key: 'izshowall',
component: PictureDownloadVue,
inFilterList: false,
},
}

@ -42,13 +42,13 @@ export const asideMap: Recordable<AsideEntity> = {
key: 'izplan', key: 'izplan',
component: PlanVue, component: PlanVue,
}, },
// izsimilarity: { izsimilarity: {
// label: '相似度阈值', label: '相似度阈值',
// defaultValue: [0,100], defaultValue: [0, 100],
// isDefaultFilter: false, isDefaultFilter: false,
// key: 'izsimilarity', key: 'izsimilarity',
// component: SimilarityVue, component: SimilarityVue,
// }, },
izyear: { izyear: {
label: '年份', label: '年份',
defaultValue: null, defaultValue: null,
@ -69,6 +69,7 @@ export const asideMap: Recordable<AsideEntity> = {
isDefaultFilter: false, isDefaultFilter: false,
key: 'izupload', key: 'izupload',
component: PictureUploadVue, component: PictureUploadVue,
inFilterList: false,
}, },
izcustomtype: { izcustomtype: {
label: '客户类型', label: '客户类型',

@ -1,3 +1,6 @@
import type { AsideEntity } from './aside'
import { IzProjectVue, IztaskrromVue, PictureDownloadVue, PlanVue, ReportUserVue, TimeVue } from '@/views/home/aside/comp/items'
export interface RowData { export interface RowData {
id: string id: string
fromtaskname: string fromtaskname: string
@ -72,3 +75,57 @@ export function findKey(columns: any[], header: string) {
const item = columns.find((column) => { return (column as any).title === header }) const item = columns.find((column) => { return (column as any).title === header })
return (item as any).key return (item as any).key
} }
// 终审左侧配置
export const asideMap: Recordable<AsideEntity> = {
izupuser: {
label: '提报人',
defaultValue: null,
isDefaultFilter: true,
key: 'izupuser',
component: ReportUserVue,
},
izproject: {
label: '所属项目',
defaultValue: null,
isDefaultFilter: true,
key: 'izproject',
component: IzProjectVue,
},
izplan: {
label: '所属计划',
defaultValue: null,
isDefaultFilter: true,
key: 'izplan',
component: PlanVue,
},
izstatus: {
label: '审批状态',
defaultValue: null,
isDefaultFilter: false,
key: 'izstatus',
component: PlanVue, // todo
},
izuptime: {
label: '提报时间',
defaultValue: null,
isDefaultFilter: false,
key: 'izuptime',
component: TimeVue,
},
iztaskrrom: {
label: '任务来源',
defaultValue: null,
isDefaultFilter: false,
key: 'iztaskrrom',
component: IztaskrromVue,
},
izshowall: {
label: '显示全部任务数据',
defaultValue: true,
isDefaultFilter: false,
key: 'izshowall',
component: PictureDownloadVue,
inFilterList: false,
},
}

@ -7,7 +7,7 @@ import type { AsideConfig } from '/#/api'
export interface ConfigState { export interface ConfigState {
systemConfig: AsideConfig | null systemConfig: AsideConfig | null
customConfig: any customConfig: string[] | null
asideValue: any asideValue: any
} }
@ -22,7 +22,7 @@ export const useAsideConfigStore = defineStore({
getConfig(): AsideConfig | null { getConfig(): AsideConfig | null {
return this.systemConfig return this.systemConfig
}, },
getCustomConfig(): any { getCustomConfig(): string[] | null {
return this.customConfig return this.customConfig
}, },
getAsideValue(): any { getAsideValue(): any {
@ -33,9 +33,6 @@ export const useAsideConfigStore = defineStore({
setConfig(config: AsideConfig) { setConfig(config: AsideConfig) {
this.systemConfig = config this.systemConfig = config
}, },
setCustomConfig(config: any) {
this.customConfig = config
},
setAsideValue(value) { setAsideValue(value) {
this.asideValue = value this.asideValue = value
}, },
@ -47,9 +44,11 @@ export const useAsideConfigStore = defineStore({
}, },
// 获取个性化配置 // 获取个性化配置
async fetchCustomConfig() { async fetchCustomConfig() {
const response = await getFilter() const res = await getFilter(0)
this.setCustomConfig(response.data) const { data } = res
return response.data const list = data && data.searchcount ? data.searchcount.split(',') : []
this.customConfig = list
return list
}, },
}, },
}) })

@ -1,6 +1,6 @@
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import { store } from '@/store' import { store } from '@/store'
import { getBackList, getIzCustomtypeList, getIzProjectList, getIzShowList, getIzcustomlevel, getIzfirmList, getIzproductnameList, getIzprojecttypeList, getIztaskrromList, getIztaskstatusList, getIzvisitcityList, getIzvisitproList, getPersonList, getPictureTypeList, getPlanList, getRegionList, getRejectList, getTFList, getizcustomnameList } from '@/api/dictionary' import { getBackList, getBusinessList, getIzShowList, getIztaskstatusList, getPictureTypeList, getRegionList, getRejectList, getRelationTypeList, getTFList, getizstatusList } from '@/api/dictionary'
export interface DictionaryState { export interface DictionaryState {
regionList: any regionList: any
@ -22,6 +22,8 @@ export interface DictionaryState {
izvisitcityList: any izvisitcityList: any
rejectList: any rejectList: any
backList: any backList: any
relationTypeList: any
izstatusList: any
} }
export const useDictionaryStore = defineStore({ export const useDictionaryStore = defineStore({
@ -46,6 +48,8 @@ export const useDictionaryStore = defineStore({
izvisitcityList: null, izvisitcityList: null,
rejectList: null, rejectList: null,
backList: null, backList: null,
relationTypeList: null,
izstatusList: null,
}), }),
getters: { getters: {
getRegionList: (state) => { getRegionList: (state) => {
@ -112,14 +116,14 @@ export const useDictionaryStore = defineStore({
}, },
// 获取提报人列表 // 获取提报人列表
async fetchPersionList() { async fetchPersionList() {
const list = await getPersonList() const list = await getBusinessList('person')
this.personList = generateOptions(list, 'id', 'upname') this.personList = list
return this.personList return this.personList
}, },
// 获取计划列表 // 获取计划列表
async fetchPlanList() { async fetchPlanList() {
const list = await getPlanList() const list = await getBusinessList('plan')
this.planList = generateOptions(list, 'id', 'planname') this.planList = list
return this.planList return this.planList
}, },
// 获取图片真假原因 // 获取图片真假原因
@ -134,71 +138,96 @@ export const useDictionaryStore = defineStore({
this.izShowList = generateOptions2(list, 'id', 'classname') this.izShowList = generateOptions2(list, 'id', 'classname')
return this.izShowList return this.izShowList
}, },
// 所属项目
async fetchIzProjectList() { async fetchIzProjectList() {
const list = await getIzProjectList() const list = await getBusinessList('project')
this.izProjectList = generateOptions(list, 'id', 'categoryname') this.izProjectList = list
return this.izProjectList return this.izProjectList
}, },
// 任务来源
async fetchIztaskrromList() { async fetchIztaskrromList() {
const list = await getIztaskrromList('1') const list = await getBusinessList('iztaskrrom')
this.izCustomtypeList = generateOptions(list) this.iztaskrromList = list
return this.izCustomtypeList return this.iztaskrromList
}, },
// 任务状态
async fetchIztaskstatusList() { async fetchIztaskstatusList() {
const list = await getIztaskstatusList('1') const list = await getBusinessList('iztaskstatus')
this.iztaskstatusList = generateOptions(list) this.iztaskstatusList = list
return this.iztaskstatusList return this.iztaskstatusList
}, },
// 地区(省信息)
async fetchIzvisitproList() { async fetchIzvisitproList() {
const list = await getIzvisitproList() const list = await getBusinessList('izvisitpro')
this.izvisitproList = generateOptions(list, 'id', 'proname') this.izvisitproList = list
return this.izvisitproList return this.izvisitproList
}, },
// 厂商
async fetchIzfirmList() { async fetchIzfirmList() {
const list = await getIzfirmList('1') const list = await getBusinessList('izfirm')
this.izfirmList = generateOptions(list) this.izfirmList = list
return this.izfirmList return this.izfirmList
}, },
// 产品名称
async fetchIzproductnameList() { async fetchIzproductnameList() {
const list = await getIzproductnameList('1') const list = await getBusinessList('izproductname')
this.izproductnameList = generateOptions(list) this.izproductnameList = list
return this.izproductnameList return this.izproductnameList
}, },
// 客户名称
async fetchizcustomnameList() { async fetchizcustomnameList() {
const list = await getizcustomnameList('1') const list = await getBusinessList('izcustomname')
this.izcustomnameList = generateOptions(list) this.izcustomnameList = list
return this.izcustomnameList return this.izcustomnameList
}, },
// 客户类型
async fetchIzCustomtypeList() { async fetchIzCustomtypeList() {
const list = await getIzCustomtypeList() const list = await getBusinessList('izcustomtype')
this.izCustomtypeList = generateOptions(list) this.izCustomtypeList = list
return this.izCustomtypeList return this.izCustomtypeList
}, },
// 客户级别
async fetchIzcustomlevelList() { async fetchIzcustomlevelList() {
const list = await getIzcustomlevel('1') const list = await getBusinessList('izcustomlevel')
this.izcustomlevelList = generateOptions(list) this.izcustomlevelList = list
return this.izcustomlevelList return this.izcustomlevelList
}, },
// 项目类别
async fetchizizprojecttypeList() { async fetchizizprojecttypeList() {
const list = await getIzprojecttypeList('1') const list = await getBusinessList('izprojecttype')
this.izizprojecttypeList = generateOptions(list) this.izizprojecttypeList = list
return this.izizprojecttypeList return this.izizprojecttypeList
}, },
// 发布地区
async fetchizvisitcityList() { async fetchizvisitcityList() {
const list = await getIzvisitcityList() const list = await getBusinessList('izvisitcity')
this.izvisitcityList = generateOptions(list) this.izvisitcityList = list
return this.izvisitcityList return this.izvisitcityList
}, },
// 拒绝原因
async fetchRejectList() { async fetchRejectList() {
const list = await getRejectList() const list = await getRejectList()
this.rejectList = generateOptions(list) this.rejectList = generateOptions(list)
return this.rejectList return this.rejectList
}, },
// 退回方式
async fetchBackList() { async fetchBackList() {
const list = await getBackList() const list = await getBackList()
this.backList = generateOptions(list) this.backList = generateOptions(list)
return this.backList return this.backList
}, },
// 退回方式
async fetchRelationTypeList() {
const list = await getRelationTypeList()
this.relationTypeList = generateOptions2(list, 'content', 'name')
return this.relationTypeList
},
// 审核状态
async fetchizstatusListt() {
const list = await getizstatusList()
this.izstatusList = generateOptions2(list, 'codeno', 'name')
return this.backList
},
}, },
}) })
@ -208,25 +237,25 @@ export function useDictionary() {
} }
// label和value都是name,不用id // label和value都是name,不用id
function generateOptions(list: any[], idkey: string = 'id', namekey: string = 'name') { function generateOptions(list: any[], valueKey: string = 'id', labelKey: string = 'name') {
const items = list || [] const items = list || []
return items.map((item) => { return items.map((item) => {
return { return {
label: item[namekey] || 'todo', label: item[labelKey] || 'todo',
value: item[namekey] || 'todo', value: item[labelKey] || 'todo',
} }
}) })
} }
// label是name,value是id // label是name,value是id
function generateOptions2(list: any[], idkey: string = 'id', namekey: string = 'name') { function generateOptions2(list: any[], valueKey: string = 'id', labelKey: string = 'name') {
const items = list || [] const items = list || []
return items.map((item) => { return items.map((item) => {
return { return {
label: item[namekey] || 'todo', label: item[labelKey] || 'todo',
value: item[idkey] || 'todo', value: item[valueKey] || 'todo',
} }
}) })
} }

@ -0,0 +1,42 @@
import { defineStore } from 'pinia'
import { store } from '@/store'
import { getFilter } from '@/api/home/filter'
export interface ConfigState {
customConfig: string[] | null
asideValue: any
}
export const useFinalStore = defineStore({
id: 'app-final',
state: (): ConfigState => ({
customConfig: null,
asideValue: null,
}),
getters: {
getCustomConfig(): string[] | null {
return this.customConfig
},
getAsideValue(): any {
return this.asideValue
},
},
actions: {
setAsideValue(value) {
this.asideValue = value
},
// 获取终审个性化配置
async fetchCustomConfig() {
const res = await getFilter(1)
const { data } = res
const list = data && data.searchcount ? data.searchcount.split(',') : []
this.customConfig = list
return list
},
},
})
// Need to be used outside the setup
export function useFinal() {
return useFinalStore(store)
}

@ -45,15 +45,15 @@ export const useTaskStore = defineStore({
}, },
async fetchApprovalList(pagination, id, refresh?: boolean) { async fetchApprovalList(pagination, id, refresh?: boolean) {
const res = await getApprovalList(pagination, id) const res = await getApprovalList(pagination, id)
this.setApprovalList(res.data)
if (res.data.length > 0) { if (res.data.length > 0) {
this.setApprovalList(res.data)
this.setActive(0) this.setActive(0)
// 审批操作完成后需要刷新为防止activeId在刷新后值不变通过此值刷新 // 审批操作完成后需要刷新为防止activeId在刷新后值不变通过此值刷新
this.refresh = !this.refresh this.refresh = !this.refresh
} }
return res.data return res
}, },
updateImmersion() { updateImmersion() {
this.immersion = !this.immersion this.immersion = !this.immersion

@ -1,21 +1,21 @@
<script lang="ts" setup> <script lang="ts" setup>
import { computed, nextTick, onBeforeMount, onMounted, reactive, ref, shallowRef, unref, watch } from 'vue' import { computed, nextTick, onBeforeMount, onMounted, reactive, ref, shallowRef, unref, watch } from 'vue'
import { CustomFilterModalVue, FilterModalVue, NewFilterModalVue } from '@/views/home/aside/comp/modals' import { CustomFilterModalVue } from '@/views/final/comp'
import Search from '@/views/home/aside/comp/Search.vue' import Search from '@/views/home/aside/comp/Search.vue'
import AdvanceFilter from '@/views/home/aside/comp/AdvanceFilter.vue' import AdvanceFilter from '@/views/home/aside/comp/AdvanceFilter.vue'
import { getViewportOffset } from '@/utils/domUtils' import { getViewportOffset } from '@/utils/domUtils'
import { useWindowSizeFn } from '@/hooks/event/useWindowSizeFn' import { useWindowSizeFn } from '@/hooks/event/useWindowSizeFn'
import { useConfig } from '@/store/modules/asideConfig' import { useFinal } from '@/store/modules/final'
import type { Filter } from '/#/home' import type { Filter } from '/#/home'
import type { AsideEntity } from '@/config/aside' import type { AsideEntity } from '@/config/aside'
import { asideMap } from '@/config/aside' import { asideMap } from '@/config/final'
import type { AsideConfig } from '/#/api' import type { AsideConfig } from '/#/api'
const configStore = useConfig() const finalStore = useFinal()
// //
const asideValue: Record<keyof typeof asideMap, any> = reactive({}) const asideValue: Record<keyof typeof asideMap, any> = reactive({})
// : // :
const asideVisible: Partial<Record<keyof AsideConfig, boolean>> = reactive({}) const asideVisible: Partial<Record<keyof AsideConfig, boolean>> = reactive({})
// //
const showItems = shallowRef<{ key: string, config: AsideEntity }[]>([]) const showItems = shallowRef<{ key: string, config: AsideEntity }[]>([])
@ -73,32 +73,37 @@ function computeSlideHeight() {
useWindowSizeFn(computeSlideHeight, 280) useWindowSizeFn(computeSlideHeight, 280)
onBeforeMount(async () => { onBeforeMount(async () => {
configStore.fetchConfig() finalStore.fetchCustomConfig()
configStore.fetchCustomConfig()
}) })
configStore.$subscribe(() => { finalStore.$subscribe(() => {
const config = configStore.getConfig const customConfig = finalStore.getCustomConfig
const customConfig = configStore.getCustomConfig
if (config === null || customConfig === null) if (customConfig === null)
return return
const showKeys = customConfig.searchcount.split(',') const showKeys: string[] = [...customConfig]
const defaultKeys = Object.keys(asideMap).filter(key => asideMap[key].isDefaultFilter)
showKeys.unshift(...defaultKeys)
Object.keys(config).forEach((key) => { Object.keys(asideMap).forEach((key) => {
//
if (key.startsWith('iz')) if (key.startsWith('iz'))
asideVisible[key] = showKeys.includes(key) && config[key] === 'Y' asideVisible[key] = asideMap[key] && (showKeys.includes(key) || asideMap[key].isDefaultFilter)
}) })
const items = showKeys.map((key: string) => { const items = showKeys.reduce((acc, key) => {
const str = key.toLowerCase() if (asideMap[key]) {
const config = {
return { key,
key: str, config: asideMap[key],
config: asideMap[str],
} }
}) return [...acc, config]
}
else {
return acc
}
}, [])
showItems.value = items showItems.value = items
}) })
@ -137,12 +142,7 @@ function filterHandler(filterList: Filter[]) {
filerMap[key] = value filerMap[key] = value
} }
Object.keys(asideValue).forEach((key) => { // TODO:
if (Object.prototype.hasOwnProperty.call(filerMap, key))
asideValue[key] = filerMap[key]
else
asideValue[key] = asideMap[key].defaultValue
})
} }
function editFilter(filter: any) { function editFilter(filter: any) {
@ -152,7 +152,7 @@ function editFilter(filter: any) {
} }
watch(asideValue, (newVal) => { watch(asideValue, (newVal) => {
configStore.setAsideValue(newVal) finalStore.setAsideValue(newVal)
}) })
</script> </script>
@ -179,10 +179,6 @@ watch(asideValue, (newVal) => {
v-model:value="asideValue[item.key]" :label="item.config.label" v-model:value="asideValue[item.key]" :label="item.config.label"
/> />
<!-- 过滤列表 -->
<FilterModalVue ref="filterModalRef" @edit-filter="editFilter" @show-new-filter="showModal(newFilterModalRef)" />
<!-- 新增过滤 -->
<NewFilterModalVue ref="newFilterModalRef" />
<!-- 筛选 --> <!-- 筛选 -->
<CustomFilterModalVue ref="customModalRef" /> <CustomFilterModalVue ref="customModalRef" />
</n-scrollbar> </n-scrollbar>
@ -217,7 +213,7 @@ watch(asideValue, (newVal) => {
height: 100%; height: 100%;
background: #507afd; background: #507afd;
position: absolute; position: absolute;
right: 0; right: -2px;
top: 0; top: 0;
z-index: 18; z-index: 18;
} }

@ -0,0 +1,417 @@
<script lang="ts" setup>
import { computed, ref, watch } from 'vue'
import { VueDraggable } from 'vue-draggable-plus'
import { debounce, difference } from 'lodash-es'
import { setFilter } from '@/api/home/filter'
import { asideMap } from '@/config/final'
import { useFinal } from '@/store/modules/final'
const show = ref(false)
const checkAll = ref(false)
const selectIds = ref<string[]>([])
const finalStore = useFinal()
function showModal() {
show.value = true
}
function closeModal() {
show.value = false
}
//
const offList = ref<any[]>([])
//
const onList = ref<any[]>([])
const allCount = computed(() => {
return `全部筛选(共${offList.value.length - 1}个)`
})
const selectCount = computed(() => {
return `全部筛选(共${onList.value.length}个)`
})
defineExpose({
showModal,
})
function generateDefaultList() {
return Object.keys(asideMap).reduce((acc, key) => {
const { label, isDefaultFilter } = asideMap[key]
//
if (isDefaultFilter) {
const config = {
id: key,
name: label || '未配置',
fix: isDefaultFilter,
checked: true,
}
return [...acc, config]
}
else {
return acc
}
}, [])
}
function generatList(customConfig) {
const keys = Object.keys(asideMap)
let onList: object[] = []
const offList: object[] = []
const showKeys = customConfig.map((key: string) => key.toLowerCase())
for (const key of keys) {
if (!key.startsWith('iz') || asideMap[key] === undefined)
continue
const name = asideMap[key]?.label
const isDefaultFilter = asideMap[key]?.isDefaultFilter
//
const isChecked = asideMap[key].isDefaultFilter || showKeys.includes(key)
offList.push({
id: key,
name: name || '未配置',
fix: isDefaultFilter,
checked: isChecked,
})
isChecked && selectIds.value.push(key)
}
onList = showKeys.reduce((acc, key) => {
const isDefaultFilter = asideMap[key]?.isDefaultFilter
// ()
if (isDefaultFilter === false) {
const config = {
id: key,
name: asideMap[key].label || '未配置',
fix: asideMap[key].isDefaultFilter,
}
return [...acc, config]
}
else {
return acc
}
}, [])
const fixedList = generateDefaultList()
onList.unshift(...fixedList)
return { showList: onList, hideList: offList }
}
finalStore.$subscribe(() => {
const customConfig = finalStore.getCustomConfig
if (customConfig === null)
return
const { showList, hideList } = generatList(customConfig)
onList.value = showList
offList.value = hideList
})
async function handleSumbit(e: MouseEvent) {
e.preventDefault()
const param = onList.value.filter(item => !asideMap[item.id].isDefaultFilter).map((item) => {
return item.id
}).join(',')
await setFilter({ searchcount: param, type: 1 })
finalStore.fetchCustomConfig()
closeModal()
}
function onCheckAllChange(value) {
const ids: string[] = []
for (const item of offList.value) {
if (!item.fix) {
item.checked = value
ids.push(item.id)
}
}
selectIds.value = value ? ids : []
}
function onCheckChange(checked: any, item: any) {
const index = selectIds.value.indexOf(item.id)
item.checked = checked
if (index === -1 && checked)
selectIds.value.push(item.id)
else
selectIds.value.splice(index, 1)
}
const showIds = computed(() => {
return onList.value.map((item) => {
return item.id
})
})
watch(
() => selectIds.value.length,
(newVal, oldVal) => {
if (newVal === oldVal)
return
const action = newVal > oldVal ? 'add' : 'remove'
const diff = action === 'add' ? difference(selectIds.value, showIds.value) : difference(showIds.value, selectIds.value)
if (diff.length === 0)
return
if (action === 'add') {
for (const item of offList.value) {
if (!item.fix && diff.includes(item.id)) {
onList.value.push({
id: item.id,
name: item.name || '未配置',
fix: item.fix || false,
})
}
}
}
else {
const list = onList.value
for (let index = 0; index < list.length; index++) {
const item = list[index]
if (!item.fix && diff.includes(item.id)) {
list.splice(index, 1)
index--
}
}
}
},
)
watch(
() => showIds.value.length,
(newVal, oldVal) => {
if (newVal === oldVal)
return
const diff = difference(selectIds.value, showIds.value)
if (diff.length === 0)
return
for (const item of offList.value) {
if (!item.fix && diff.includes(item.id)) {
const index = selectIds.value.indexOf(item.id)
item.checked = false
selectIds.value.splice(index, 1)
}
}
},
)
function clearDragSource() {
onList.value = onList.value.filter((item) => {
return item.fix === true
})
}
function removeHandler(id: string) {
const index = onList.value.findIndex((item) => {
return item.id === id
})
if (index !== -1)
onList.value.splice(index, 1)
}
const offKeyword = ref('')
const onKeyword = ref('')
const leftInputHandler = debounce((keyword) => {
offKeyword.value = keyword
}, 300)
const rightInputHandler = debounce((keyword) => {
onKeyword.value = keyword
}, 300)
</script>
<template>
<n-modal v-model:show="show" transform-origin="center" :mask-closable="false">
<n-card class="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>
<n-grid cols="24" class="mt-4 proCard" responsive="screen" :x-gap="24">
<n-grid-item span="11">
<NCard
:title="allCount" class="dragcardStyle" :segmented="{ content: true, footer: true }" size="small"
:bordered="false"
>
<div>
<n-input placeholder="搜索关键字" @input="leftInputHandler">
<template #suffix>
<SvgIcon size="14px" name="magnifying-1" />
</template>
</n-input>
<n-scrollbar style="max-height: 500px;border: 1px solid #cad2dd;border-radius: 2px;">
<div class="draggable-ul">
<div class="draggable-li">
<n-checkbox v-model:checked="checkAll" label="全部" @update:checked="onCheckAllChange" />
</div>
<div
v-for="item in offList" v-show="item.name.includes(offKeyword)" :key="item.id"
:class="{ 'disable-check': item.fix }" class="draggable-li"
>
<n-checkbox
v-model:checked="item.checked" :label="item.name" :disabled="item.fix"
@update:checked="onCheckChange($event, item)"
/>
</div>
</div>
</n-scrollbar>
</div>
</NCard>
</n-grid-item>
<n-grid-item style="display: flex;align-items: center;" span="2">
<SvgIcon size="20" name="switchsvg" />
</n-grid-item>
<n-grid-item span="11">
<NCard
:title="selectCount" class="dragcardStyle" :segmented="{ content: true, footer: true }" size="small"
:bordered="false"
>
<template #header-extra>
<span class="textbtnStyle" @click="clearDragSource"></span>
</template>
<div>
<n-input placeholder="搜索关键字" @input="rightInputHandler">
<template #suffix>
<SvgIcon size="14px" name="magnifying-1" />
</template>
</n-input>
<n-scrollbar style="max-height: 500px;border: 1px solid #cad2dd;border-radius: 2px;" class="scroll">
<VueDraggable v-model="onList" class="draggable-ul" filter=".draggable-li[draggable='false']" :animation="150" group="shared">
<div
v-for="item in onList" v-show="item.name.includes(onKeyword)" :key="item.id" :draggable="!item.fix"
:class="{ fix: item.fix }" class="cursor-move draggable-li"
>
<SvgIcon v-show="!item.fix" name="drag" size="24" />
<span class="ml-2">{{ item.name }}</span>
<SvgIcon
v-if="!item.fix" size="16px" style="display:block;margin-left: auto;cursor: pointer;"
name="clear" @click="removeHandler(item.id)"
/>
</div>
</VueDraggable>
</n-scrollbar>
</div>
</NCard>
</n-grid-item>
</n-grid>
</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;
}
&-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;
}
}
}
.dragcardStyle {
--n-padding-bottom: 0px !important;
--n-padding-left: 0px !important;
}
.cardstyle {
width: 620px;
height: 800px;
--n-padding-bottom: 20px;
--n-padding-left: 24px;
}
.textbtnStyle {
cursor: pointer;
color: #1980FF;
}
.draggable-ul {
width: 100%;
overflow: hidden;
.draggable-li {
width: 100%;
padding: 10px 16px;
color: #333;
border-bottom: 1px solid #efeff5;
display: flex;
align-items: center;
}
.disable-check {
color: gainsboro;
}
}
::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
}
</style>

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

@ -454,7 +454,7 @@ function reload() {
<style lang="less" scoped> <style lang="less" scoped>
.wrapper { .wrapper {
display: flex; display: flex;
flex: auto; flex: 1;
overflow: hidden; overflow: hidden;
flex-direction: column; flex-direction: column;
box-sizing: border-box; box-sizing: border-box;

@ -85,11 +85,13 @@ configStore.$subscribe(() => {
if (config === null || customConfig === null) if (config === null || customConfig === null)
return return
const showKeys = customConfig.searchcount.split(',') const showKeys = [...customConfig].filter(key => !asideMap[key].isDefaultFilter)
const defaultKeys = Object.keys(asideMap).filter(key => asideMap[key].isDefaultFilter)
showKeys.unshift(...defaultKeys)
Object.keys(config).forEach((key) => { Object.keys(config).forEach((key) => {
if (key.startsWith('iz')) if (key.startsWith('iz') && asideMap[key] !== undefined)
asideVisible[key] = showKeys.includes(key) && config[key] === 'Y' asideVisible[key] = (showKeys.includes(key) || asideMap[key].isDefaultFilter) && config[key] === 'Y'
}) })
const items = showKeys.reduce((acc, key) => { const items = showKeys.reduce((acc, key) => {

@ -78,7 +78,7 @@ async function featchList() {
loading = true loading = true
try { try {
const searchParam: FilterSearchParam = { search_searchname: { value: keyword.value, op: 'like', type: 'string' } } const searchParam: FilterSearchParam = { search_searchname: { value: keyword.value, op: 'like', type: 'string' } }
const result = await getConditionList(pagination, searchParam) const result = await getConditionList(pagination, searchParam, 0)
const { data } = result const { data } = result
// pagination.pageNo += 1 // pagination.pageNo += 1
// canloadMore = pageCount >= pagination.pageNo // canloadMore = pageCount >= pagination.pageNo

@ -23,8 +23,7 @@ const inputHandler = debounce((keyword) => {
configStore.$subscribe(() => { configStore.$subscribe(() => {
const customConfig = configStore.getCustomConfig const customConfig = configStore.getCustomConfig
const searchcount = customConfig?.searchcount || '' const keys = customConfig ? [...customConfig] : []
const keys = searchcount ? searchcount.split(',') : []
if (keys.length === 0) if (keys.length === 0)
return return

@ -62,7 +62,7 @@ function generatList(config, customConfig) {
const keys = Object.keys(config) const keys = Object.keys(config)
let onList: object[] = [] let onList: object[] = []
const offList: object[] = [] const offList: object[] = []
const showKeys = customConfig.searchcount.split(',').map((key: string) => key.toLowerCase()) const showKeys = [...customConfig]
for (const key of keys) { for (const key of keys) {
if (!key.startsWith('iz') || config[key] === 'N' || asideMap[key] === undefined) if (!key.startsWith('iz') || config[key] === 'N' || asideMap[key] === undefined)
@ -87,8 +87,10 @@ function generatList(config, customConfig) {
} }
onList = showKeys.reduce((acc, key) => { onList = showKeys.reduce((acc, key) => {
// const isDefaultFilter = asideMap[key]?.isDefaultFilter
if (config[key] === 'Y') {
// && ()
if (config[key] === 'Y' && isDefaultFilter === false) {
const config = { const config = {
id: key, id: key,
name: asideMap[key].label || '未配置', name: asideMap[key].label || '未配置',
@ -103,6 +105,7 @@ function generatList(config, customConfig) {
const fixedList = generateDefaultList(config) const fixedList = generateDefaultList(config)
offList.unshift(...fixedList) offList.unshift(...fixedList)
onList.unshift(...fixedList)
return { showList: onList, hideList: offList } return { showList: onList, hideList: offList }
} }
@ -121,11 +124,11 @@ configStore.$subscribe(() => {
async function handleSumbit(e: MouseEvent) { async function handleSumbit(e: MouseEvent) {
e.preventDefault() e.preventDefault()
const param = onList.value.map((item) => { const param = onList.value.filter(item => !asideMap[item.id].isDefaultFilter).map((item) => {
return item.id return item.id
}).join(',') }).join(',')
await setFilter({ searchcount: param }) await setFilter({ searchcount: param, type: 0 })
configStore.fetchCustomConfig() configStore.fetchCustomConfig()
closeModal() closeModal()
} }
@ -304,12 +307,12 @@ const rightInputHandler = debounce((keyword) => {
</template> </template>
</n-input> </n-input>
<n-scrollbar style="max-height: 500px;border: 1px solid #cad2dd;border-radius: 2px;" class="scroll"> <n-scrollbar style="max-height: 500px;border: 1px solid #cad2dd;border-radius: 2px;" class="scroll">
<VueDraggable v-model="onList" class="draggable-ul" :animation="150" group="shared"> <VueDraggable v-model="onList" filter=".draggable-li[draggable='false']" class="draggable-ul" :animation="150" group="shared">
<div <div
v-for="item in onList" v-show="item.name.includes(onKeyword)" :key="item.id" :class="{ fix: item.fix }" v-for="item in onList" v-show="item.name.includes(onKeyword)" :key="item.id" :draggable="!item.fix" :class="{ fix: item.fix }"
class="cursor-move draggable-li" class="cursor-move draggable-li"
> >
<SvgIcon name="drag" size="24" /> <SvgIcon v-show="!item.fix" name="drag" size="24" />
<span class="ml-2">{{ item.name }}</span> <span class="ml-2">{{ item.name }}</span>
<SvgIcon <SvgIcon
v-if="!item.fix" size="16px" style="display:block;margin-left: auto;cursor: pointer;" v-if="!item.fix" size="16px" style="display:block;margin-left: auto;cursor: pointer;"

@ -81,14 +81,14 @@ const loading = ref(true)
const pagination = reactive({ const pagination = reactive({
page: 1, page: 1,
pageCount: 1, pageCount: 1,
pageSize: 2, pageSize: 10,
}) })
const tableData = ref<Array<RowData>>([]) const tableData = ref<Array<RowData>>([])
const keyword = ref('') const keyword = ref('')
async function query(page: number, pageSize: number) { async function query(page: number, pageSize: number) {
const searchParam: FilterSearchParam = { search_searchname: { value: keyword.value, op: 'like', type: 'string' } } const searchParam: FilterSearchParam = { search_searchname: { value: keyword.value, op: 'like', type: 'string' } }
const result = await getConditionList({ pageNo: page, pageSize }, searchParam) const result = await getConditionList({ pageNo: page, pageSize }, searchParam, 0)
const { data, pageCount } = result const { data, pageCount } = result
tableData.value = data tableData.value = data
pagination.page = page pagination.page = page
@ -99,7 +99,7 @@ async function query(page: number, pageSize: number) {
function afterLeave() { function afterLeave() {
pagination.page = 1 pagination.page = 1
pagination.pageCount = 1 pagination.pageCount = 1
pagination.pageSize = 5 pagination.pageSize = 10
} }
const selectionIds = ref<DataTableRowKey[]>([]) const selectionIds = ref<DataTableRowKey[]>([])
@ -239,7 +239,7 @@ defineExpose({
const inputHandler = debounce((word) => { const inputHandler = debounce((word) => {
keyword.value = word keyword.value = word
query(1, 10) query(1, 5)
}, 300) }, 300)
</script> </script>

@ -1,11 +1,12 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { FormInst, FormItemRule, FormRules } from 'naive-ui' import type { FormInst, FormItemRule, FormRules } from 'naive-ui'
import { computed, defineOptions, reactive, ref, unref, watch } from 'vue' import { computed, defineOptions, onBeforeMount, reactive, ref, unref, watch } from 'vue'
import { asideMap } from '@/config/aside' import { asideMap } from '@/config/aside'
import { useDictionary } from '@/store/modules/dictonary' import { useDictionary } from '@/store/modules/dictonary'
import { useConfig } from '@/store/modules/asideConfig' import { useConfig } from '@/store/modules/asideConfig'
import type { FilterCondition } from '/#/api' import type { FilterCondition } from '/#/api'
import { addCondition, updateCondition } from '@/api/home/filter' import { addCondition, updateCondition } from '@/api/home/filter'
import { formatToDate2 } from '@/utils/dateUtil'
defineOptions({ name: 'NewFilterModal' }) defineOptions({ name: 'NewFilterModal' })
@ -95,24 +96,27 @@ const formValue = reactive<FormType>({
function handleSumbit(e: MouseEvent) { function handleSumbit(e: MouseEvent) {
e.preventDefault() e.preventDefault()
const v = formRef.value
formRef.value?.validate((errors) => { formRef.value?.validate((errors) => {
if (errors) if (errors)
return return
const list = formValue.conditions.map((item) => { const list = formValue.conditions.map((item, index) => {
const { type, operator, result } = item const { type, operator, result } = item
return { return {
searchfield: type!, searchfield: type!,
searchtype: operator!, searchtype: operator!,
searchvalue: result!, searchvalue: formatValue(type!, result),
searchRelationType: formValue.logic!,
orderNum: index + 1,
} }
}) })
const param: FilterCondition = { const param: FilterCondition = {
searchname: formValue.name!, searchname: formValue.name!,
type: 0,
ocrUsersearchchildList: list, ocrUsersearchchildList: list,
logic: formValue.logic!,
} }
if (currentStatus.value === 'new') if (currentStatus.value === 'new')
@ -123,6 +127,19 @@ function handleSumbit(e: MouseEvent) {
}) })
} }
function formatValue(searchfield: string, searchvalue: any) {
if (searchfield === 'izyear') {
const start = formatToDate2(searchvalue[0])
const end = formatToDate2(searchvalue[1])
return `${start}-${end}`
}
if (Array.isArray(searchvalue))
return searchvalue.join(',')
return searchvalue
}
function createCondition() { function createCondition() {
formValue.conditions.push({ formValue.conditions.push({
type: null, type: null,
@ -152,16 +169,7 @@ const operatorOptions = [
}, },
] ]
const logicOptions = [ const logicOptions = ref([])
{
label: '与',
value: 'and',
},
{
label: '或',
value: 'or',
},
]
const similarityOptions = [ const similarityOptions = [
{ {
@ -178,6 +186,14 @@ const similarityOptions = [
}, },
] ]
onBeforeMount(() => {
dicStore.fetchRelationTypeList()
})
watch(() => dicStore.relationTypeList, (newval) => {
logicOptions.value = newval
})
const resultOptions = ref<Option[]>([]) const resultOptions = ref<Option[]>([])
function showModal() { function showModal() {
@ -293,8 +309,7 @@ defineExpose({
/> />
</n-space> </n-space>
<n-select <n-select
v-else v-model:value="item.result" style="margin-left: 8px;" placeholder="请选择" v-else v-model:value="item.result" style="margin-left: 8px;" placeholder="请选择" :options="resultOptions"
:options="resultOptions"
/> />
<n-button :style="noBorderInput" icon-placement="right" @click="removeCondition(index)"> <n-button :style="noBorderInput" icon-placement="right" @click="removeCondition(index)">
<template #icon> <template #icon>

@ -4,22 +4,17 @@ import imagesloaded from 'imagesloaded'
import { debounce } from 'lodash-es' import { debounce } from 'lodash-es'
import Masonry from 'masonry-layout' import Masonry from 'masonry-layout'
import { useMessage } from 'naive-ui' import { useMessage } from 'naive-ui'
import { computed, nextTick, onBeforeMount, onMounted, onUnmounted, onUpdated, reactive, ref, unref, watch } from 'vue' import { computed, nextTick, onMounted, onUnmounted, onUpdated, reactive, ref, unref, watch } from 'vue'
import GeneratePackageModal from './modal/GeneratePackageModal.vue' import GeneratePackageModal from './modal/GeneratePackageModal.vue'
import PackageSettingsModal from './modal/PackageSettingsModal.vue' import PackageSettingsModal from './modal/PackageSettingsModal.vue'
import LoginSuccessModal from './modal/LoginSuccessModal.vue' import LoginSuccessModal from './modal/LoginSuccessModal.vue'
import { getPictureList, oneClickCheck } from '@/api/home/main' import { getPictureList, oneClickCheck } from '@/api/home/main'
import img1 from '@/assets/images/1.jpg' import avatar from '@/assets/images/avatar.jpg'
import img2 from '@/assets/images/2.jpg'
import img3 from '@/assets/images/3.jpg'
import img4 from '@/assets/images/4.jpg'
import img5 from '@/assets/images/5.jpg'
import { timeOptions, viewOptions } from '@/config/home' import { timeOptions, viewOptions } from '@/config/home'
import { useWindowSizeFn } from '@/hooks/event/useWindowSizeFn' import { useWindowSizeFn } from '@/hooks/event/useWindowSizeFn'
import { useConfig } from '@/store/modules/asideConfig' import { useConfig } from '@/store/modules/asideConfig'
import { getViewportOffset } from '@/utils/domUtils' import { getViewportOffset } from '@/utils/domUtils'
import { hideDownload } from '@/utils/image' import { hideDownload } from '@/utils/image'
import { randomInt } from '@/utils/index'
import emitter from '@/utils/mitt' import emitter from '@/utils/mitt'
import { getImgUrl } from '@/utils/urlUtils' import { getImgUrl } from '@/utils/urlUtils'
@ -31,7 +26,7 @@ const el = ref<HTMLDivElement | null>(null)
const viewMode = ref('masonry') const viewMode = ref('masonry')
const pagination = reactive({ const pagination = reactive({
pageNo: 0, pageNo: 0,
pageSize: 30, pageSize: 50,
}) })
const configStore = useConfig() const configStore = useConfig()
const packageModalRef = ref(null) const packageModalRef = ref(null)
@ -72,15 +67,13 @@ const layout = debounce(() => {
_imagesload = imagesloaded('.grid-item') _imagesload = imagesloaded('.grid-item')
// _imagesload.on('always', (instance) => {
// console.log('always')
// })
_imagesload.on('done', (instance) => { _imagesload.on('done', (instance) => {
(_masonry as any).layout() (_masonry as any).layout()
if (!el.value)
return
const scrollHeight = el.value!.scrollHeight const scrollHeight = el.value!.scrollHeight
const clientHeight = el.value!.clientHeight const clientHeight = el.value!.clientHeight
const top = scrollHeight - clientHeight - 20 const top = scrollHeight - clientHeight - 100
el.value!.scrollTo({ top, behavior: 'instant' }) el.value!.scrollTo({ top, behavior: 'instant' })
loading.value = false loading.value = false
}) })
@ -133,19 +126,6 @@ const viewLabel = computed(() => {
const listData = ref<any[]>([]) const listData = ref<any[]>([])
const urls = [
img1,
img2,
img3,
img4,
img5,
]
function randomUrl() {
const index = randomInt(0, urls.length)
return urls[index]
}
async function featchList() { async function featchList() {
loading.value = true loading.value = true
try { try {
@ -155,10 +135,9 @@ async function featchList() {
} }
pagination.pageNo += 1 pagination.pageNo += 1
const result = await getPictureList({ ...pagination, ...contentParams })
// TODO const filterParams = unref(configStore.getAsideValue)
// result.data = Array.from({ length: 30 }) const result = await getPictureList({ ...pagination, ...contentParams, ...filterParams })
// result.pageCount = 1
const { data, pageCount } = result const { data, pageCount } = result
canloadMore = pageCount >= pagination.pageNo && pageCount > 0 canloadMore = pageCount >= pagination.pageNo && pageCount > 0
@ -187,11 +166,6 @@ async function loadMore() {
listData.value.push(...more) listData.value.push(...more)
} }
// onBeforeMount(async () => {
// const list = await featchList()
// listData.value = list
// })
const gridHeight = computed(() => { const gridHeight = computed(() => {
return viewMode.value !== 'masonry' ? '145px' : '' return viewMode.value !== 'masonry' ? '145px' : ''
}) })
@ -251,10 +225,11 @@ watch(() => configStore.asideValue, (newVal, oldVal) => {
}, { deep: true }) }, { deep: true })
async function refreshHandler() { async function refreshHandler() {
pagination.pageNo = 1 pagination.pageNo = 0
pagination.pageSize = 30 pagination.pageSize = 50
listData.value.length = 0 listData.value.length = 0
loading.value = true loading.value = true
canloadMore = true
const contentParams = { const contentParams = {
search_month: timeRange.value, search_month: timeRange.value,
@ -277,35 +252,39 @@ async function refreshHandler() {
listData.value = list listData.value = list
} }
function getAvatar(url: string): string {
return url ? getImgUrl(url) : avatar
}
</script> </script>
<template> <template>
<div class="wrapper"> <div class="wrapper">
<div class="wrapper-header"> <div class="wrapper-header">
<div class="wrapper-header-left"> <div class="left">
<SvgIcon size="32" name="magnifying" /> <SvgIcon size="32" name="magnifying" />
<span class="wrapper-header-font">AI一键查重</span> <span class="font">AI一键查重</span>
</div> </div>
<SvgIcon style="cursor: pointer;" size="105" name="yijianchachong" @click="oneCheck" /> <SvgIcon style="cursor: pointer;" size="105" name="yijianchachong" @click="oneCheck" />
</div> </div>
<div class="wrapper-content"> <div class="wrapper-content">
<div class="wrapper-content-form"> <div class="form">
<n-popselect v-model:value="timeRange" :options="timeOptions" trigger="click"> <n-popselect v-model:value="timeRange" :options="timeOptions" trigger="click">
<div class="wrapper-content-dropdown"> <div class="dropdown">
<span>{{ timeLabel || '请选择' }}</span> <span>{{ timeLabel || '请选择' }}</span>
<SvgIcon class="wrapper-content-dropdown-gap" name="arrow-botton" size="14" /> <SvgIcon class="gap" name="arrow-botton" size="14" />
</div> </div>
</n-popselect> </n-popselect>
<n-popselect v-model:value="viewMode" :options="viewOptions" trigger="click"> <n-popselect v-model:value="viewMode" :options="viewOptions" trigger="click">
<div class="wrapper-content-dropdown"> <div class="dropdown">
<span>{{ viewLabel || '请选择' }}</span> <span>{{ viewLabel || '请选择' }}</span>
<SvgIcon class="wrapper-content-dropdown-gap" name="arrow-botton" size="14" /> <SvgIcon class="gap" name="arrow-botton" size="14" />
</div> </div>
</n-popselect> </n-popselect>
</div> </div>
<n-spin :show="loading">
<div ref="el" class="scroll" :style="listStyle"> <div ref="el" class="scroll" :style="listStyle">
<!-- <n-scrollbar :on-scroll="scrollHandler"> --> <!-- <n-scrollbar :on-scroll="scrollHandler"> -->
<n-spin :show="loading">
<div ref="masonryRef" class="grid"> <div ref="masonryRef" class="grid">
<div v-for="(item, index) in listData" :key="index" :style="{ height: gridHeight }" class="grid-item"> <div v-for="(item, index) in listData" :key="index" :style="{ height: gridHeight }" class="grid-item">
<!-- <div :style="{ 'background-color': randomColor(0.2) }" class="wrapper-content-item-img" /> --> <!-- <div :style="{ 'background-color': randomColor(0.2) }" class="wrapper-content-item-img" /> -->
@ -313,22 +292,25 @@ async function refreshHandler() {
class="wrapper-content-item-img" :class="{ 'wrapper-content-item-img-fit': viewMode !== 'masonry' }" class="wrapper-content-item-img" :class="{ 'wrapper-content-item-img-fit': viewMode !== 'masonry' }"
:src="item.imgUrl" :src="item.imgUrl"
> --> > -->
<n-image class="wrapper-content-item-img" :img-props="{ onClick: hideDownload }" :class="{ 'wrapper-content-item-img-fit': viewMode !== 'masonry' }" :src="item.imgUrl" /> <n-image
<div class="wrapper-content-item-info"> class="img" :img-props="{ onClick: hideDownload }"
<div class="wrapper-content-item-info-left"> :class="{ 'img-fit': viewMode !== 'masonry' }" :src="item.imgUrl"
<n-avatar :src="getImgUrl(item.uphead)" class="wrapper-content-item-info-avatar" round /> />
<div class="info">
<div class="left">
<n-avatar :src="getAvatar(item.uphead)" class="avatar" round />
<span>{{ item.upname }}</span> <span>{{ item.upname }}</span>
</div> </div>
<div class="wrapper-content-item-info-right"> <div class="right">
<span :style="{ marginRight: '5px' }">分类</span> <span :style="{ marginRight: '5px' }">分类</span>
<span>{{ item.ocrPictureclass?.classname }}</span> <span>{{ item.ocrPictureclass?.classname }}</span>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</n-spin>
<!-- </n-scrollbar> --> <!-- </n-scrollbar> -->
</div> </div>
</n-spin>
</div> </div>
<PackageSettingsModal ref="packageModalRef" @commit="commitHandler" /> <PackageSettingsModal ref="packageModalRef" @commit="commitHandler" />
<GeneratePackageModal ref="generateModalRef" /> <GeneratePackageModal ref="generateModalRef" />
@ -357,12 +339,12 @@ async function refreshHandler() {
border-radius: 3px; border-radius: 3px;
width: 100%; width: 100%;
&-left { .left {
display: flex; display: flex;
align-items: center; align-items: center;
} }
&-font { .font {
font-size: 18px; font-size: 18px;
font-weight: bold; font-weight: bold;
color: #333333; color: #333333;
@ -379,55 +361,53 @@ async function refreshHandler() {
border-radius: 3px; border-radius: 3px;
border: 1px solid rgb(239, 239, 245); border: 1px solid rgb(239, 239, 245);
&-form { .form {
display: flex; display: flex;
align-items: center; align-items: center;
font-size: 14px; font-size: 14px;
padding-bottom: 16px; padding-bottom: 16px;
} }
&-item { .img {
&-img {
border-radius: 7px; border-radius: 7px;
display: block; display: block;
height: calc(100% - 20px); height: calc(100% - 25px);
} }
&-img-fit { .img-fit {
width: 100%; width: 100%;
object-fit: cover; overflow: hidden;
} }
&-info { .info {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
margin-top: 4px; margin-top: 4px;
&-left { .left {
display: flex; display: flex;
align-items: center; align-items: center;
} }
&-right { .right {
display: flex; display: flex;
align-items: center; align-items: center;
} }
&-avatar { .avatar {
width: 15px; width: 15px;
height: 15px; height: 15px;
margin-right: 5px; margin-right: 5px;
} }
} }
}
&-dropdown { .dropdown {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
align-items: center; align-items: center;
margin-right: 24px; margin-right: 24px;
&-gap { .gap {
margin-left: 5px; margin-left: 5px;
} }
} }
@ -435,7 +415,8 @@ async function refreshHandler() {
.grid-item { .grid-item {
width: 182px; width: 182px;
border-radius: 7px; border-radius: 7px;
margin-bottom: 20px; margin-bottom: 10px;
overflow: hidden;
} }
.scroll { .scroll {

@ -7,9 +7,6 @@ import { useMessage } from 'naive-ui'
import { PageEnum } from '@/enums/pageEnum' import { PageEnum } from '@/enums/pageEnum'
import { useUserStore } from '@/store/modules/user' import { useUserStore } from '@/store/modules/user'
import { ResultEnum } from '@/enums/httpEnum' import { ResultEnum } from '@/enums/httpEnum'
import { getFilter, setFilter } from '@/api/home/filter'
import { getConfig } from '@/api/system/user'
import { asideMap } from '@/config/aside'
import { getCode, smsLogin } from '@/api/login/login' import { getCode, smsLogin } from '@/api/login/login'
const emit = defineEmits(['close', 'forget']) const emit = defineEmits(['close', 'forget'])
@ -79,20 +76,6 @@ function handleSubmit(e) {
const { code, message: msg } = await userStore.login(params) const { code, message: msg } = await userStore.login(params)
if (code === ResultEnum.SUCCESS) { if (code === ResultEnum.SUCCESS) {
await userStore.getInformation() await userStore.getInformation()
const response = await getFilter()
//
if (response.data === null) {
const systemConfig = await getConfig()
const onList: string[] = []
Object.keys(systemConfig.data).forEach((key) => {
//
if (key.startsWith('iz') && systemConfig.data[key] === 'Y' && asideMap[key]?.isDefaultFilter)
onList.push(key)
})
await setFilter({ searchcount: onList.join(',') })
}
message.destroyAll() message.destroyAll()
const toPath = decodeURIComponent((route.query?.redirect || '/') as string) const toPath = decodeURIComponent((route.query?.redirect || '/') as string)
@ -134,19 +117,6 @@ function handleSmsSubmit(e) {
if (code === ResultEnum.SUCCESS) { if (code === ResultEnum.SUCCESS) {
// const { code, message: msg } = await userStore.login(params) // const { code, message: msg } = await userStore.login(params)
await userStore.getInformation() await userStore.getInformation()
const response = await getFilter()
//
if (response.data === null) {
const systemConfig = await getConfig()
const onList: string[] = []
Object.keys(systemConfig.data).forEach((key) => {
//
if (key.startsWith('iz') && systemConfig.data[key] === 'Y' && asideMap[key]?.isDefaultFilter)
onList.push(key)
})
await setFilter({ searchcount: onList.join(',') })
}
message.destroyAll() message.destroyAll()
const toPath = decodeURIComponent((route.query?.redirect || '/') as string) const toPath = decodeURIComponent((route.query?.redirect || '/') as string)

@ -6,9 +6,6 @@ import captcha from './captcha.vue'
import { PageEnum } from '@/enums/pageEnum' import { PageEnum } from '@/enums/pageEnum'
import { useUserStore } from '@/store/modules/user' import { useUserStore } from '@/store/modules/user'
import { ResultEnum } from '@/enums/httpEnum' import { ResultEnum } from '@/enums/httpEnum'
import { getFilter, setFilter } from '@/api/home/filter'
import { getConfig } from '@/api/system/user'
import { asideMap } from '@/config/aside'
interface FormState { interface FormState {
enterprisecode?: string enterprisecode?: string
@ -59,20 +56,6 @@ function handleSubmit(e) {
try { try {
const { code, message: msg } = await userStore.login(params) const { code, message: msg } = await userStore.login(params)
await userStore.getInformation() await userStore.getInformation()
const response = await getFilter()
//
if (response.data === null) {
const systemConfig = await getConfig()
const onList: string[] = []
Object.keys(systemConfig.data).forEach((key) => {
//
if (key.startsWith('iz') && systemConfig.data[key] === 'Y' && asideMap[key]?.isDefaultFilter)
onList.push(key)
})
await setFilter({ searchcount: onList.join(',') })
}
message.destroyAll() message.destroyAll()
if (code === ResultEnum.SUCCESS) { if (code === ResultEnum.SUCCESS) {
const toPath = decodeURIComponent((route.query?.redirect || '/') as string) const toPath = decodeURIComponent((route.query?.redirect || '/') as string)

@ -1,19 +1,14 @@
<script lang="ts" setup> <script lang="ts" setup>
import { useTaskStore } from '@/store/modules/task'
import { useUser } from '@/store/modules/user'
import emitter from '@/utils/mitt'
import { computed, onBeforeMount, onMounted, onUnmounted, reactive, ref, unref, watch } from 'vue' import { computed, onBeforeMount, onMounted, onUnmounted, reactive, ref, unref, watch } from 'vue'
import { debounce } from 'lodash-es'
import TaskList from './TaskList.vue' import TaskList from './TaskList.vue'
import type { TaskListItem } from '/#/task' import { useTaskStore } from '@/store/modules/task'
import { useUser } from '@/store/modules/user'
const CustomFieldModalRef = ref(null) const CustomFieldModalRef = ref(null)
const collapse = ref(false) const collapse = ref(false)
const taskStore = useTaskStore() const taskStore = useTaskStore()
const userStore = useUser() const taskListRef = ref<HTMLDivElement | null>(null)
const pagination = reactive({
pageNo: 1,
pageSize: 10,
})
function collapseHandler() { function collapseHandler() {
collapse.value = !collapse.value collapse.value = !collapse.value
@ -33,49 +28,30 @@ const collapseIcon = computed(() => {
return collapse.value ? 'expand-cir' : 'collapse-cir' return collapse.value ? 'expand-cir' : 'collapse-cir'
}) })
const data = ref<TaskListItem[]>([])
onBeforeMount(async () => {
const id = userStore.getUserInfo.id
const orderList = await taskStore.fetchApprovalList(pagination, id)
data.value = orderList
})
const count = computed(() => {
return data.value.length
})
const asideEnter = ref(false) const asideEnter = ref(false)
const showCollapse = computed(() => { const showCollapse = computed(() => {
return collapse.value ? true : asideEnter.value return collapse.value ? true : asideEnter.value
}) })
onMounted(() => {
emitter.on('refresh', refreshHandler)
})
onUnmounted(() => {
emitter.off('refresh', refreshHandler)
})
async function refreshHandler() {
pagination.pageNo = 1
pagination.pageSize = 10
const id = userStore.getUserInfo.id
const orderList = await taskStore.fetchApprovalList(pagination, id)
data.value = orderList
}
watch(() => taskStore.immersion, () => { watch(() => taskStore.immersion, () => {
collapse.value = true collapse.value = true
}) })
function showFilterModal() { function showFilter() {
const modal = unref(CustomFieldModalRef)! as any const modal = unref(CustomFieldModalRef)! as any
modal.showModal() modal.showModal()
} }
const showSearch = ref(false)
function setShowSearch(value: boolean) {
showSearch.value = value
}
const inputHandler = debounce((word) => {
(taskListRef.value as any).search(word)
}, 500)
</script> </script>
<template> <template>
@ -86,16 +62,29 @@ function showFilterModal() {
</div> </div>
</div> </div>
<div class="aside-header"> <div class="aside-header">
<div class="aside-header-left"> <div v-show="!showSearch" class="warpper">
<div class="left">
<svg-icon name="all-worksheet" size="32" /> <svg-icon name="all-worksheet" size="32" />
<span class="aside-header-title">所有请求({{ count }})</span> <span style="margin-left: 8px;">所有请求</span>
</div>
<div class="right">
<SvgIcon
style="cursor: pointer;margin-left: 10px;" size="18" name="magnifying-1"
@click="setShowSearch(true)"
/>
<SvgIcon style="cursor: pointer;margin-left: 10px;" size="18" name="filter" @click="showFilter" />
</div> </div>
<div class="aside-header-right"> </div>
<SvgIcon size="18" name="magnifying-1" /> <div v-show="showSearch" class="warpper">
<SvgIcon style="margin-left: 10px;cursor: pointer;" size="18" name="filter" @click="showFilterModal" /> <n-input style="flex: 1;height: 32px;" placeholder="请输入你需要搜索的内容" @input="inputHandler">
<template #suffix>
<SvgIcon size="14px" name="magnifying-1" />
</template>
</n-input>
<SvgIcon size="16px" style="margin-left: 6px;cursor: pointer;" name="clear" @click="setShowSearch(false)" />
</div> </div>
</div> </div>
<TaskList style="height: calc(100vh - 146px);" class="work-sheet-list" :data="data" :active-id="taskStore.getActiveId!" /> <TaskList ref="taskListRef" style="height: calc(100vh - 146px);" class="work-sheet-list" />
<CustomFieldModal ref="CustomFieldModalRef" /> <CustomFieldModal ref="CustomFieldModalRef" />
</div> </div>
</template> </template>
@ -111,13 +100,16 @@ function showFilterModal() {
box-sizing: border-box; box-sizing: border-box;
&-header { &-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 16px; padding: 12px 16px;
width: 100%; width: 100%;
overflow: hidden; overflow: hidden;
.warpper {
display: flex;
justify-content: space-between;
align-items: center;
}
&-title { &-title {
margin-left: 8px; margin-left: 8px;
color: #333333; color: #333333;
@ -125,13 +117,13 @@ function showFilterModal() {
font-weight: bold; font-weight: bold;
} }
&-left { .left {
display: flex; display: flex;
align-items: center; align-items: center;
overflow: hidden; overflow: hidden;
} }
&-right { .right {
display: flex; display: flex;
align-items: center; align-items: center;
overflow: hidden; overflow: hidden;
@ -150,7 +142,7 @@ function showFilterModal() {
height: 100%; height: 100%;
background: #507afd; background: #507afd;
position: absolute; position: absolute;
right: 0; right: -2px;
top: 0; top: 0;
} }

@ -1,33 +1,115 @@
<script lang="ts" setup> <script lang="ts" setup>
import { onMounted, onUnmounted, reactive, ref, watch } from 'vue'
import { useInfiniteScroll } from '@vueuse/core'
import ListItem from './ListItem.vue' import ListItem from './ListItem.vue'
import { useTaskStore } from '@/store/modules/task' import { useTaskStore } from '@/store/modules/task'
import { useUser } from '@/store/modules/user'
import emitter from '@/utils/mitt'
defineOptions({ name: 'WorkSheetList' }) defineOptions({ name: 'WorkSheetList' })
defineProps({ const taskStore = useTaskStore()
activeId: { const data = ref<any[]>([])
type: String, const activeId = ref('')
required: true, const el = ref<HTMLDivElement | null>(null)
const keyword = ref('')
const canloadMore = ref(true)
const userStore = useUser()
const pagination = reactive({
pageNo: 0,
pageSize: 10,
})
function selectHandler(id: string, index: number) {
taskStore.setActive(index)
}
const { isLoading } = useInfiniteScroll(
el as any,
() => {
loadMore()
}, },
data: { { distance: 10, interval: 300, canLoadMore: () => {
type: Object as PropType<any[]>, // console.log('canloadmore excuted!')
required: true, return canloadMore.value
} },
)
async function loadMore() {
if (isLoading.value || el.value == null)
return
const more = await fetchList()
data.value.push(...more)
}
async function fetchList() {
try {
pagination.pageNo += 1
const id = userStore.getUserInfo.id
const result = await taskStore.fetchApprovalList(pagination, id)
const { data, pageCount } = result
canloadMore.value = pageCount >= pagination.pageNo && pageCount !== 0
return data || []
}
catch (error) {
canloadMore.value = false
return []
}
}
watch(() => taskStore.activeId, (newVal) => {
activeId.value = newVal
})
function reset() {
pagination.pageNo = 0
pagination.pageSize = 10
canloadMore.value = true
data.value.length = 0
}
async function search(word: string) {
keyword.value = word
reset()
useInfiniteScroll(
el as any,
() => {
loadMore()
}, },
{ distance: 10, canLoadMore: () => canloadMore.value },
)
}
onMounted(() => {
emitter.on('refresh', refreshHandler)
}) })
const taskStore = useTaskStore() onUnmounted(() => {
emitter.off('refresh', refreshHandler)
})
function selectHandler(id: string, index: number) { async function refreshHandler() {
taskStore.setActive(index) reset()
search('')
} }
defineExpose({
search,
})
</script> </script>
<template> <template>
<n-scrollbar class="wrapper"> <n-scrollbar>
<n-spin :show="isLoading">
<div ref="el">
<ListItem <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.formid" :list-item="item"
@click="selectHandler(item.id, index)" @click="selectHandler(item.id, index)"
/> />
</div>
</n-spin>
</n-scrollbar> </n-scrollbar>
</template> </template>

@ -67,20 +67,20 @@ function validate(items: any[]) {
if (items.length === 0) if (items.length === 0)
return '至少选中一个任务' return '至少选中一个任务'
const useInfo = userStore.getUserInfo // const useInfo = userStore.getUserInfo
const username = useInfo.loginname // const username = useInfo.loginname
for (const item of items) { // for (const item of items) {
const { iztrueorfalse, states, assignee } = item // const { iztrueorfalse, states, assignee } = item
if (iztrueorfalse === null) // if (iztrueorfalse === null)
return '未判别真假' // return ''
else if (states !== 2) // else if (states !== 2)
return '审批状态不合法' // return ''
else if (assignee !== username) // else if (assignee !== username)
return '审批人不一致' // return ''
} // }
return null return null
} }

@ -74,6 +74,9 @@ const showSearch = ref(false)
function setShowSearch(value: boolean) { function setShowSearch(value: boolean) {
showSearch.value = value showSearch.value = value
if (value === false)
(packageListRef.value as any).search('')
} }
const inputHandler = debounce((word) => { const inputHandler = debounce((word) => {

@ -36,7 +36,7 @@ async function loadMore() {
if (isLoading.value || el.value == null) if (isLoading.value || el.value == null)
return return
console.log('loadmore') // console.log('loadmore')
const more = await fetchList() const more = await fetchList()
data.value.push(...more) data.value.push(...more)
} }

@ -65,17 +65,17 @@ function validate(items: any[]) {
if (items.length === 0) if (items.length === 0)
return '至少选中一个任务' return '至少选中一个任务'
for (const item of items) { // for (const item of items) {
const { iztrueorfalse, history, states } = item // const { iztrueorfalse, history, states } = item
if (iztrueorfalse !== null) // if (iztrueorfalse !== null)
return '存在已经辨识过的任务' // return ''
else if (history) // else if (history)
return '包含历史数据' // return ''
else if (states !== 1 && states !== 2) // else if (states !== 1 && states !== 2)
return '审批状态不合法' // return ''
} // }
return null return null
} }

9
types/api.d.ts vendored

@ -24,8 +24,8 @@ export interface ConditionEntry {
export interface FilterCondition { export interface FilterCondition {
searchname: string searchname: string
type: number
ocrUsersearchchildList: ConditionEntry[] ocrUsersearchchildList: ConditionEntry[]
logic: string
} }
export interface FilterUpdate extends FilterCondition { export interface FilterUpdate extends FilterCondition {
@ -33,6 +33,7 @@ export interface FilterUpdate extends FilterCondition {
} }
export interface FilterParam { export interface FilterParam {
type: number
searchcount: string searchcount: string
} }
@ -128,3 +129,9 @@ export interface ResetParam {
fromid: string fromid: string
taskid: string taskid: string
} }
export interface BusinessParam {
pageNo: string
pageSize: string
field: string
}

Loading…
Cancel
Save