数通智联化工云平台
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

167 lines
4.0 KiB

<!--
@ 作者: 秦东
@ 时间: 2023-07-12 10:58:26
@ 备注: 快速选择表单字段
-->
<script lang='ts' setup>
import { FormData,FormList } from '@/api/DesignForm/types'
import { stringToObj } from '@/utils/DesignForm/form'
import { jsonParseStringify } from '@/utils/DesignForm'
import controlListData from '@/components/DesignForm/assembly'
import { getRequest } from '@/api/DesignForm'
import Draggable from 'vuedraggable-es'
import UseTemplate from './template.vue'
const props = withDefaults(
defineProps<{
formId?: number | string
}>(),
{}
)
// 默认搜索允许显示的字段
const searchField = [
'input',
'radio',
'checkbox',
'select',
'datePicker',
'timePicker',
'inputNumber',
'cascader',
'component',
'button'
]
const designType = inject('formDesignType') as string
const formDataList = ref<any[]>([])
const isSearch = computed(() => {
return designType === 'search'
})
const emits = defineEmits(["clickCheck","click"]);
// 筛选设计时左则勾选已有表单字段
const selectChange = (val: any,obj: FormList) => {
if (val) {
// 勾选时追加
const newObj = jsonParseStringify(obj)
delete newObj.rules
delete newObj.customRules
emits('clickCheck', newObj)
}
}
const controlList = computed(() => {
if (designType === 'search') {
// 只返回基础字段
const temp: any = []
controlListData.forEach((item: any) => {
if (item.children) {
const filter = item.children.filter((ch: any) => {
return searchField.includes(ch.type)
})
if (filter && filter.length) {
temp.push({ title: item.title, children: filter })
}
}
})
return temp
} else {
return controlListData
}
})
//使用模版
const useTemplateEl = ref()
const useTemplateClick = () => {
useTemplateEl.value.open()
}
const useTemplateSelect = (data: FormData) => {
emits('click', data)
}
const clone = (origin: any) => {
return jsonParseStringify(origin)
}
//数据监听
watch(
() => props.formId,
(val: any) => {
if (val && isSearch.value) {
getFormField(val)
}
}
)
// 加载当前列表所属的表单,从表单中提取可用于搜索的字段
const getFormField = (formId: number) => {
getRequest('designById', { id: formId }).then((res: any) => {
const data = stringToObj(res.data.data)
if (data && data.list) {
forEachGetData(data.list)
}
})
}
const forEachGetData = (data: FormList[]) => {
data.forEach((item: any) => {
if (item.type === 'grid' || item.type === 'tabs') {
item.columns.forEach((col: any) => {
forEachGetData(col.list)
})
} else if (item.type === 'card') {
forEachGetData(item.list)
} else if (searchField.includes(item.type) && item.type !== 'button') {
formDataList.value.push(item)
}
})
}
</script>
<template>
<div class="components-list">
<div v-if="isSearch && formDataList?.length">
<div class="title">快速选择表单字段</div>
<div class="content">
<el-checkbox
v-for="item in formDataList"
:key="item.name"
@change="selectChange($event,item)"
>
{{ item.item?.label }}
</el-checkbox>
</div>
</div>
<!--组件主体-->
<div v-for="(list, index) in controlList" :key="index">
<div class="title">
{{ list.title }}
<div
class="template"
v-if="index === 0 && !isSearch"
@click="useTemplateClick"
>
使用模板
</div>
</div>
<draggable
itemKey="key123"
tag="ul"
v-model="list.children"
:group="{ name: 'form', pull: 'clone', put: false }"
ghost-class="ghost"
:sort="false"
:clone="clone"
>
<template #item="{ element }">
<li :class="[element.type]">
<i :class="`icon-${element.icon}`"></i>
<span :title="element.label">{{ element.label }}</span>
</li>
</template>
</draggable>
</div>
<use-template
2 years ago
v-if="!isSearch"
ref="useTemplateEl"
@click="useTemplateSelect"
/>
</div>
</template>
<style lang='scss' scoped>
</style>