feat: 高级筛选组件props调整,任务审批高级筛选筛选值赋值

pull/37/head
刘释隆 1 year ago
parent bc51e033ee
commit ceb024784b

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

@ -129,3 +129,92 @@ export const asideMap: Recordable<AsideEntity> = {
inFilterList: false,
},
}
// 审批添加筛选配置 (左侧)
export const asideTaskMap: Recordable<AsideEntity> = {
izstatus: {
label: '审批状态',
defaultValue: null,
isDefaultFilter: true,
key: 'izstatus'
},
izuptime: {
label: '提报时间',
defaultValue: null,
isDefaultFilter: true,
key: 'izuptime'
},
izupuser: {
label: '提报人',
defaultValue: null,
isDefaultFilter: true,
key: 'izupuser'
},
izprojecttype: {
label: '任务类型',
defaultValue: null,
isDefaultFilter: true,
key: 'izprojecttype'
},
iztaskrrom: {
label: '任务来源',
defaultValue: null,
isDefaultFilter: true,
key: 'iztaskrrom'
},
izcustomname: {
label: '拜访客户',
defaultValue: null,
isDefaultFilter: true,
key: 'izcustomname'
},
izcustomtype: {
label: '客户类型',
defaultValue: null,
isDefaultFilter: true,
key: 'izcustomtype'
},
izproject: {
label: '所属项目',
defaultValue: null,
isDefaultFilter: true,
key: 'izproject'
},
izvisitpro: {
label: '拜访省份/直辖市',
defaultValue: null,
isDefaultFilter: true,
key: 'izvisitpro'
},
izcustomlevel: {
label: '客户级别',
defaultValue: null,
isDefaultFilter: true,
key: 'izcustomlevel'
},
izprojecttype: {
label: '项目类别',
defaultValue: null,
isDefaultFilter: true,
key: 'izprojecttype'
},
izproductname: {
label: '产品名称',
defaultValue: null,
isDefaultFilter: true,
key: 'izproductname'
},
izvisitcity: {
label: '拜访城市',
defaultValue: null,
isDefaultFilter: true,
key: 'izvisitcity'
},
izfirm: {
label: '厂商',
defaultValue: null,
isDefaultFilter: true,
key: 'izfirm'
}
}

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

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

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

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

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