Browse Source

tableForm

master
zhangli 1 year ago
parent
commit
1fadb218bb
  1. 3
      src/components/TableForm/index.ts
  2. 120
      src/components/TableForm/src/TableForm.vue
  3. 50
      src/hooks/web/useCrudSchemas.ts
  4. 44
      src/types/tableForm.d.ts
  5. 78
      src/utils/disposition/tableColumns.ts
  6. 30
      src/views/wms/itembasic/ItembasicForm.vue

3
src/components/TableForm/index.ts

@ -0,0 +1,3 @@
import Annex from './src/Annex.vue'
export { Annex }

120
src/components/TableForm/src/TableForm.vue

@ -0,0 +1,120 @@
<!-- 附件组件 -->
<template>
<div class="table-form">
<el-table
class="multipleTableComponents"
ref="TableBaseComponents_Ref"
v-loading="tableLoading"
:data="tableData"
:height="height"
row-key="id"
:border="border"
@selection-change="tableSelectionChange"
@sort-change="tableSortChange"
@row-click="handleTableSelect"
style="{width:100%}"
>
<!-- 多选 -->
<el-table-column
fixed="left"
:reserve-selection="true"
type="selection"
:width="50"
/>
<!-- 序号 -->
<el-table-column
type="index"
fixed="left"
label="序号"
width="80"
:align="'center'"
/>
<el-table-column
v-slot="{ row }"
v-for="headerItem in tableFields"
:key="headerItem"
:fixed="headerItem.tableForm &&headerItem.tableForm.fixed? headerItem.tableForm.fixed:''"
:label="headerItem.label"
:prop="headerItem.field"
:sortable="headerItem.tableForm && headerItem.tableForm.sortable ? headerItem.tableForm.sortable:''"
:width="headerItem.tableForm && headerItem.tableForm.width ? headerItem.tableForm.width : '100'"
>
<el-form
ref="TableBaseForm_Ref"
:model="row"
:rules="tableFormRules"
:class="tableFormRules ? '' : 'noRulesForm'"
>
<el-form-item >
<el-input
v-model="row[headerItem.field]"
/>
</el-form-item>
</el-form>
</el-table-column>
<slot></slot>
<template #empty>
<el-empty class="vab-data-empty" description="暂无数据" />
</template>
</el-table>
</div>
</template>
<script lang="ts" setup>
const props = defineProps({
// :custom="headerItem.sortable?headerItem.sortable:false"
selectionTable: {
type: Boolean,
default: false,
},
//
isShowIndex: {
type: Boolean,
default: false,
},
//
tableLoading: {
type: Boolean,
default: false,
},
//
tableData: {
type: Array,
default: () => {
return []
},
},
//
tableFields: {
type: Array,
default: () => {
return []
},
},
// table
height: {
type: [Number, String],
default: () => {
return '650'
}
},
//
border: {
type: Boolean,
default: true,
},
// tablerules
tableFormRules: {
type: Object,
default: null
}
})
console.log(props.tableFields);
</script>
<style scoped lang="scss">
</style>

50
src/hooks/web/useCrudSchemas.ts

@ -7,6 +7,7 @@ import { getBoolDictOptions, getDictOptions, getIntDictOptions } from '@/utils/d
import { FormSchema } from '@/types/form' import { FormSchema } from '@/types/form'
import { TableColumn } from '@/types/table' import { TableColumn } from '@/types/table'
import { DescriptionsSchema } from '@/types/descriptions' import { DescriptionsSchema } from '@/types/descriptions'
import { TableFormColumn } from '@/types/tableForm'
import { ComponentOptions, ComponentProps } from '@/types/components' import { ComponentOptions, ComponentProps } from '@/types/components'
import { DictTag } from '@/components/DictTag' import { DictTag } from '@/components/DictTag'
import { cloneDeep, merge } from 'lodash-es' import { cloneDeep, merge } from 'lodash-es'
@ -20,6 +21,8 @@ export type CrudSchema = Omit<TableColumn, 'children'> & {
form?: CrudFormParams // 表单的详细配置 form?: CrudFormParams // 表单的详细配置
isDetail?: boolean // 是否在详情显示 isDetail?: boolean // 是否在详情显示
detail?: CrudDescriptionsParams // 详情的详细配置 detail?: CrudDescriptionsParams // 详情的详细配置
isTableForm?: boolean // 是否在表格嵌套表单显示
tableForm?: CrudTableFormParams // 表格嵌套表单的详细配置
children?: CrudSchema[] children?: CrudSchema[]
dictType?: string // 字典类型 dictType?: string // 字典类型
dictClass?: 'string' | 'number' | 'boolean' // 字典数据类型 string | number | boolean dictClass?: 'string' | 'number' | 'boolean' // 字典数据类型 string | number | boolean
@ -54,11 +57,16 @@ type CrudDescriptionsParams = {
show?: boolean show?: boolean
} & Omit<DescriptionsSchema, 'field'> } & Omit<DescriptionsSchema, 'field'>
type CrudTableFormParams = {
// 是否显示表单项
show?: boolean
} & Omit<TableFormColumn, 'field'>
interface AllSchemas { interface AllSchemas {
searchSchema: FormSchema[] searchSchema: FormSchema[]
tableColumns: TableColumn[] tableColumns: TableColumn[]
formSchema: FormSchema[] formSchema: FormSchema[]
detailSchema: DescriptionsSchema[] detailSchema: DescriptionsSchema[]
tableFormColumns: TableFormColumn[]
} }
const { t } = useI18n() const { t } = useI18n()
@ -74,7 +82,8 @@ export const useCrudSchemas = (
searchSchema: [], searchSchema: [],
tableColumns: [], tableColumns: [],
formSchema: [], formSchema: [],
detailSchema: [] detailSchema: [],
tableFormColumns:[]
}) })
const searchSchema = filterSearchSchema(crudSchema, allSchemas) const searchSchema = filterSearchSchema(crudSchema, allSchemas)
@ -89,6 +98,8 @@ export const useCrudSchemas = (
const detailSchema = filterDescriptionsSchema(crudSchema) const detailSchema = filterDescriptionsSchema(crudSchema)
allSchemas.detailSchema = detailSchema allSchemas.detailSchema = detailSchema
const tableFormColumns= filterTableFormSchema(crudSchema)
allSchemas.tableFormColumns =tableFormColumns || []
return { return {
allSchemas allSchemas
} }
@ -187,7 +198,36 @@ const filterTableSchema = (crudSchema: CrudSchema[]): TableColumn[] => {
return !!data.field return !!data.field
}) })
} }
// 过滤 tableForm 结构
const filterTableFormSchema = (crudSchema: CrudSchema[]): TableFormColumn[] => {
const tableFormColumns = treeMap<CrudSchema>(crudSchema, {
conversion: (schema: CrudSchema) => {
if (schema?.isTableForm !== false && schema?.tableForm?.show !== false) {
// add by 芋艿:增加对 dict 字典数据的支持
if (!schema.formatter && schema.dictType) {
schema.formatter = (_: Recordable, __: TableFormColumn, cellValue: any) => {
return h(DictTag, {
type: schema.dictType!, // ! 表示一定不为空
value: cellValue
})
}
}
return {
...schema.tableForm,
...schema
}
}
}
})
// 第一次过滤会有 undefined 所以需要二次过滤
return filter<TableFormColumn>(tableFormColumns as TableFormColumn[], (data) => {
if (data.children === void 0) {
delete data.children
}
return !!data.field
})
}
// 过滤 form 结构 // 过滤 form 结构
const filterFormSchema = (crudSchema: CrudSchema[], allSchemas: AllSchemas): FormSchema[] => { const filterFormSchema = (crudSchema: CrudSchema[], allSchemas: AllSchemas): FormSchema[] => {
const formSchema: FormSchema[] = [] const formSchema: FormSchema[] = []
@ -324,3 +364,11 @@ export const sortTableColumns = (tableColumns: TableColumn[], field: string) =>
// 添加到开头 // 添加到开头
tableColumns.unshift(fieldColumn) tableColumns.unshift(fieldColumn)
} }
// 将 tableColumns 指定 fields 放到最前面
export const sortTableFormColumns = (tableFormColumns: TableFormColumn[], field: string) => {
const fieldIndex = tableFormColumns.findIndex((item) => item.field === field)
const fieldColumn = cloneDeep(tableFormColumns[fieldIndex])
tableFormColumns.splice(fieldIndex, 1)
// 添加到开头
tableFormColumns.unshift(fieldColumn)
}

44
src/types/tableForm.d.ts

@ -0,0 +1,44 @@
import type { CSSProperties } from 'vue'
import { ColProps, ComponentProps, ComponentName } from '@/types/components'
import type { AxiosPromise } from 'axios'
export type TableFormSetPropsType = {
field: string
path: string
value: any
}
export type TableFormValueType = string | number | string[] | number[] | boolean | undefined | null
export type TableFormItemProps = {
labelWidth?: string | number
required?: boolean
rules?: Recordable
error?: string
showMessage?: boolean
inlineMessage?: boolean
style?: CSSProperties
}
export type TableFormSchema = {
// 唯一值
field: string
// 标题
label?: string
// 提示
labelMessage?: string
// col组件属性
colProps?: ColProps
// 表单组件属性,slots对应的是表单组件的插槽,规则:${field}-xxx,具体可以查看element-plus文档
componentProps?: { slots?: Recordable } & ComponentProps
// formItem组件属性
formItemProps?: FormItemProps
// 渲染的组件
component?: ComponentName
// 初始值
value?: FormValueType
// 是否隐藏
hidden?: boolean
// 远程加载下拉项
api?: <T = any>() => AxiosPromise<T>
}

78
src/utils/disposition/tableColumns.ts

@ -9,8 +9,12 @@ export const ItemBasic = useCrudSchemas(reactive<CrudSchema[]>([
field: 'code', field: 'code',
sort: 'custom', sort: 'custom',
table: { table: {
width: 150 width:700
} },
tableForm:{
width: 300,
sortable:false
}
}, },
{ {
label: '名称', label: '名称',
@ -18,6 +22,10 @@ export const ItemBasic = useCrudSchemas(reactive<CrudSchema[]>([
sort: 'custom', sort: 'custom',
table: { table: {
width: 150 width: 150
},
tableForm:{
width: 300,
sortable:false
} }
}, },
{ {
@ -26,7 +34,8 @@ export const ItemBasic = useCrudSchemas(reactive<CrudSchema[]>([
sort: 'custom', sort: 'custom',
table: { table: {
width: 150 width: 150
} } ,
isTableForm:false
}, },
{ {
label: '描述2', label: '描述2',
@ -34,7 +43,8 @@ export const ItemBasic = useCrudSchemas(reactive<CrudSchema[]>([
sort: 'custom', sort: 'custom',
table: { table: {
width: 150 width: 150
} } ,
isTableForm:false
}, },
{ {
label: '状态', label: '状态',
@ -49,7 +59,7 @@ export const ItemBasic = useCrudSchemas(reactive<CrudSchema[]>([
width: 100 width: 100
} , } ,
form: { form: {
component: 'Select', component: 'Switch',
} }
}, },
{ {
@ -74,7 +84,8 @@ export const ItemBasic = useCrudSchemas(reactive<CrudSchema[]>([
isTable: true, isTable: true,
table: { table: {
width: 150 width: 150
} } ,
isTableForm:false
}, },
{ {
label: '是否标包', label: '是否标包',
@ -104,7 +115,8 @@ export const ItemBasic = useCrudSchemas(reactive<CrudSchema[]>([
}, },
form: { form: {
component: 'Radio', component: 'Radio',
} },
isTableForm:false
}, },
{ {
label: '可制造', label: '可制造',
@ -134,7 +146,8 @@ export const ItemBasic = useCrudSchemas(reactive<CrudSchema[]>([
} , } ,
form: { form: {
component: 'Radio', component: 'Radio',
} },
isTableForm:false
}, },
{ {
label: '回收件', label: '回收件',
@ -149,7 +162,8 @@ export const ItemBasic = useCrudSchemas(reactive<CrudSchema[]>([
}, },
form: { form: {
component: 'Radio', component: 'Radio',
} },
isTableForm:false
}, },
{ {
label: '虚零件', label: '虚零件',
@ -164,7 +178,8 @@ export const ItemBasic = useCrudSchemas(reactive<CrudSchema[]>([
} , } ,
form: { form: {
component: 'Radio', component: 'Radio',
} },
isTableForm:false
}, },
{ {
label: 'ABC类', label: 'ABC类',
@ -176,7 +191,8 @@ export const ItemBasic = useCrudSchemas(reactive<CrudSchema[]>([
isTable: true, isTable: true,
table: { table: {
width: 100 width: 100
} } ,
isTableForm:false
}, },
{ {
label: '类型', label: '类型',
@ -188,7 +204,8 @@ export const ItemBasic = useCrudSchemas(reactive<CrudSchema[]>([
isTable: true, isTable: true,
table: { table: {
width: 100 width: 100
} } ,
isTableForm:false
}, },
{ {
label: '种类', label: '种类',
@ -200,7 +217,8 @@ export const ItemBasic = useCrudSchemas(reactive<CrudSchema[]>([
isTable: true, isTable: true,
table: { table: {
width: 100 width: 100
} } ,
isTableForm:false
}, },
{ {
label: '分组', label: '分组',
@ -212,7 +230,8 @@ export const ItemBasic = useCrudSchemas(reactive<CrudSchema[]>([
isTable: true, isTable: true,
table: { table: {
width: 100 width: 100
} } ,
isTableForm:false
}, },
{ {
label: '颜色', label: '颜色',
@ -224,7 +243,8 @@ export const ItemBasic = useCrudSchemas(reactive<CrudSchema[]>([
isTable: true, isTable: true,
table: { table: {
width: 100 width: 100
} } ,
isTableForm:false
}, },
{ {
label: '配置', label: '配置',
@ -236,7 +256,8 @@ export const ItemBasic = useCrudSchemas(reactive<CrudSchema[]>([
isTable: true, isTable: true,
table: { table: {
width: 100 width: 100
} } ,
isTableForm:false
}, },
{ {
label: '项目', label: '项目',
@ -244,7 +265,8 @@ export const ItemBasic = useCrudSchemas(reactive<CrudSchema[]>([
sort: 'custom', sort: 'custom',
table: { table: {
width: 100 width: 100
} } ,
isTableForm:false
}, },
{ {
label: '质量等级', label: '质量等级',
@ -256,7 +278,8 @@ export const ItemBasic = useCrudSchemas(reactive<CrudSchema[]>([
isTable: true, isTable: true,
table: { table: {
width: 120 width: 120
} } ,
isTableForm:false
}, },
{ {
label: '有效天数', label: '有效天数',
@ -267,7 +290,8 @@ export const ItemBasic = useCrudSchemas(reactive<CrudSchema[]>([
}, },
form: { form: {
component: 'InputNumber', component: 'InputNumber',
} },
isTableForm:false
}, },
{ {
label: '是否可用', label: '是否可用',
@ -282,7 +306,8 @@ export const ItemBasic = useCrudSchemas(reactive<CrudSchema[]>([
}, },
form: { form: {
component: 'Radio', component: 'Radio',
} },
isTableForm:false
}, },
{ {
label: '生效时间', label: '生效时间',
@ -320,7 +345,8 @@ export const ItemBasic = useCrudSchemas(reactive<CrudSchema[]>([
componentProps: { componentProps: {
type: 'datetimerange', type: 'datetimerange',
} }
} },
isTableForm:false
}, },
{ {
label: '创建时间', label: '创建时间',
@ -334,10 +360,11 @@ export const ItemBasic = useCrudSchemas(reactive<CrudSchema[]>([
}, },
table: { table: {
width: 120 width: 120
} } ,
isTableForm:false
}, },
{ label: '备注', field: 'remark', sort: 'custom', isTable: false }, { label: '备注', field: 'remark', sort: 'custom', isTable: false,isTableForm:false},
{ label: '创建者ID', field: 'creator', sort: 'custom', isTable: false, isForm: false }, { label: '创建者ID', field: 'creator', sort: 'custom', isTable: false, isForm: false,isTableForm:false },
{ {
label: '操作', label: '操作',
field: 'action', field: 'action',
@ -345,7 +372,8 @@ export const ItemBasic = useCrudSchemas(reactive<CrudSchema[]>([
isForm: false , isForm: false ,
table: { table: {
width: 150 width: 150
} },
isTableForm:false
} }
])) ]))

30
src/views/wms/itembasic/ItembasicForm.vue

@ -4,21 +4,21 @@
<Form ref="formRef" v-loading="formLoading" :rules="ItemBasicRules" :schema="ItemBasic.allSchemas.formSchema" <Form ref="formRef" v-loading="formLoading" :rules="ItemBasicRules" :schema="ItemBasic.allSchemas.formSchema"
:model="formData" :is-col="true" /> :model="formData" :is-col="true" />
<div class="table"> <div class="table">
<Table :columns="columns" /> <TableForm :tableFields="ItemBasic.allSchemas.tableFormColumns" :tableData="tableData"/>
</div> </div>
</div> </div>
<template #footer> <template #footer>
<!-- 列表头部 --> <!-- 列表头部 -->
<TableHead :HeadButttondata="Butttondata" @buttonBaseClick="buttonBaseClick" /> <TableHead :HeadButttondata="Butttondata" @buttonBaseClick="buttonBaseClick" />
</template> </template>
</Dialog> </Dialog>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import * as ItembasicApi from '@/api/wms/itembasic' import * as ItembasicApi from '@/api/wms/itembasic'
import { ItemBasic, ItemBasicRules } from '@/utils/disposition/tableColumns.ts' import { ItemBasic, ItemBasicRules } from '@/utils/disposition/tableColumns.ts'
import TableForm from '@/components/TableForm/src/TableForm.vue'
import * as defaultButtons from '@/utils/disposition/defaultButtons' import * as defaultButtons from '@/utils/disposition/defaultButtons'
console.log(ItemBasic);
const { t } = useI18n() // const { t } = useI18n() //
const message = useMessage() // const message = useMessage() //
@ -124,14 +124,27 @@ const buttonBaseClick = (val, item) => {
dialogVisible.value = false dialogVisible.value = false
} }
} }
const columns = ref([{
label: '物品号', const tableData = ref([{
code: 'GOODS-0202-12',
name:'物料',
unit:'吨',
num: '20'
}, { }, {
label: '物品名称', code: 'GOODS-0202-12',
name: '物料',
unit: '吨',
num: '20'
}, { }, {
label: '单位', code: 'GOODS-0202-12',
name: '物料',
unit: '吨',
num: '20'
}, { }, {
label: '数量', code: 'GOODS-0202-12',
name: '物料',
unit: '吨',
num: '20'
}]) }])
</script> </script>
<style scoped> <style scoped>
@ -139,5 +152,6 @@ const columns = ref([{
border: 1px solid #dedede; border: 1px solid #dedede;
border-radius: 8px; border-radius: 8px;
padding: 10px; padding: 10px;
display: flex;
} }
</style> </style>

Loading…
Cancel
Save