Merge pull request 'feat: 高级筛选组件props调整,任务审批高级筛选筛选值赋值' (#37) from al into test
Reviewed-on: #37pull/38/head
commit
4ad22908d0
@ -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…
Reference in new issue