|
|
@@ -1,20 +1,10 @@
|
|
|
<script setup lang="ts">
|
|
|
import { ElMessage, ElMessageBox, type FormProps } from 'element-plus'
|
|
|
import type { PropType } from 'vue'
|
|
|
+import type { BasicForm, BasicFormItem } from '@/types/form'
|
|
|
+import router from '@/router'
|
|
|
+import type { RouteLocationNormalized } from 'vue-router'
|
|
|
|
|
|
-interface column {
|
|
|
- label?: string
|
|
|
- value: string
|
|
|
- name: string
|
|
|
- formType: string
|
|
|
- placeholder: string
|
|
|
- options: Array<any>
|
|
|
- rules: any
|
|
|
- search: boolean
|
|
|
- width: string | number
|
|
|
- type: string
|
|
|
- span: number
|
|
|
-}
|
|
|
interface CRUD {
|
|
|
create: Function
|
|
|
update: Function
|
|
|
@@ -23,27 +13,27 @@ interface CRUD {
|
|
|
getRecord: Function
|
|
|
}
|
|
|
const props = defineProps({
|
|
|
- crud: Object as PropType<CRUD>,
|
|
|
+ crud: {
|
|
|
+ required: true,
|
|
|
+ type: Object as PropType<CRUD>
|
|
|
+ },
|
|
|
pageSize: {
|
|
|
type: Number,
|
|
|
default: 10
|
|
|
},
|
|
|
- columns: {
|
|
|
- type: Array as PropType<column[]>,
|
|
|
- default: () => []
|
|
|
- },
|
|
|
selection: {
|
|
|
type: Boolean,
|
|
|
default: true
|
|
|
},
|
|
|
- form: Object as PropType<FormProps>,
|
|
|
- formItem: Object,
|
|
|
- formComp: Object
|
|
|
+ form: {
|
|
|
+ type: Object as PropType<BasicForm>,
|
|
|
+ required: true
|
|
|
+ }
|
|
|
})
|
|
|
|
|
|
// ============== 查询部分开始 ===============
|
|
|
const query = ref<any>({})
|
|
|
-const searchList = computed(() => props.columns.filter(item => item.search))
|
|
|
+const searchList = computed(() => props?.form.formItems.filter(item => item.search))
|
|
|
const handleQuery = () => {
|
|
|
curPage.value = 1
|
|
|
getTableData()
|
|
|
@@ -83,19 +73,28 @@ const handleSelectionChange = (columns: any[]) => {
|
|
|
// ============== 表格部分结束 ===============
|
|
|
|
|
|
// ============== crud部分开始 ===============
|
|
|
+const formRoute = props.form.route
|
|
|
const handleCreate = () => {
|
|
|
- dialogTitle.value = '新增'
|
|
|
- dialogVisible.value = true
|
|
|
+ if (formRoute) {
|
|
|
+ router.push(formRoute)
|
|
|
+ } else {
|
|
|
+ dialogTitle.value = '新增'
|
|
|
+ dialogVisible.value = true
|
|
|
+ }
|
|
|
}
|
|
|
const handleUpdate = (row: any) => {
|
|
|
- dialogTitle.value = '编辑'
|
|
|
- dialogVisible.value = true
|
|
|
- if (props.crud?.getRecord) {
|
|
|
- props.crud.getRecord({ id: row.id }).then((res: any) => {
|
|
|
- formData.value = res.data
|
|
|
- })
|
|
|
+ if (formRoute) {
|
|
|
+ router.push(formRoute)
|
|
|
} else {
|
|
|
- formData.value = row
|
|
|
+ dialogTitle.value = '编辑'
|
|
|
+ dialogVisible.value = true
|
|
|
+ if (props.crud?.getRecord) {
|
|
|
+ props.crud.getRecord({ id: row.id }).then((res: any) => {
|
|
|
+ formData.value = res.data
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ formData.value = row
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
const handleDelete = (id: string | number) => {
|
|
|
@@ -115,57 +114,32 @@ const handlePatchDelete = () => {}
|
|
|
// ============== crud部分结束 ===============
|
|
|
|
|
|
// ============== 表单部分开始 ===============
|
|
|
-const formConfig: any = ref({
|
|
|
- labelWidth: '100px',
|
|
|
- labelPosition: 'top',
|
|
|
- size: 'large',
|
|
|
- ...props.form
|
|
|
-})
|
|
|
+const formData = ref<any>({})
|
|
|
+const formRef = ref()
|
|
|
const dialogTitle = ref('新增')
|
|
|
const dialogVisible = ref(false)
|
|
|
|
|
|
-const closeDialog = () => {
|
|
|
- dialogVisible.value = false
|
|
|
- formData.value = {}
|
|
|
-}
|
|
|
+props.form?.formItems.forEach(item => {
|
|
|
+ formData.value[item.name] = item.value
|
|
|
+})
|
|
|
|
|
|
-const formData = ref<any>({})
|
|
|
-const formRef = ref()
|
|
|
-const formList = computed(() => props.columns.filter(item => item.formType))
|
|
|
-const placeholder = (item: column) => {
|
|
|
- if (['select'].includes(item.formType)) {
|
|
|
+const placeholder = (item: BasicFormItem) => {
|
|
|
+ if (['select'].includes(item.type)) {
|
|
|
return '请选择' + item.label
|
|
|
} else {
|
|
|
return '请输入' + item.label
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-formList.value.forEach(item => {
|
|
|
- formData.value[item.name] = item.value
|
|
|
-})
|
|
|
+const closeDialog = () => {
|
|
|
+ dialogVisible.value = false
|
|
|
+ formData.value = {}
|
|
|
+}
|
|
|
|
|
|
const submit = () => {
|
|
|
- let res, message
|
|
|
- formRef.value.validate(async (valid: boolean) => {
|
|
|
- if (valid) {
|
|
|
- if (formData.value.id) {
|
|
|
- res = props.crud?.update(formData.value)
|
|
|
- message = '新增成功'
|
|
|
- } else {
|
|
|
- res = props.crud?.create(formData.value)
|
|
|
- message = '修改成功'
|
|
|
- }
|
|
|
-
|
|
|
- if (res.code === 0) {
|
|
|
- ElMessage({
|
|
|
- type: 'success',
|
|
|
- message
|
|
|
- })
|
|
|
- closeDialog()
|
|
|
- }
|
|
|
- }
|
|
|
- })
|
|
|
+ formRef.value.submit().then(() => closeDialog())
|
|
|
}
|
|
|
+
|
|
|
// ============== 表单部分结束 ===============
|
|
|
</script>
|
|
|
|
|
|
@@ -175,11 +149,11 @@ const submit = () => {
|
|
|
<el-form :inline="true">
|
|
|
<el-form-item :label="item.label" v-for="item in searchList">
|
|
|
<component
|
|
|
- :is="'el-' + item.formType"
|
|
|
+ :is="'el-' + item.type"
|
|
|
v-model="query[item.name]"
|
|
|
:placeholder="item.placeholder || placeholder(item)"
|
|
|
>
|
|
|
- <template v-if="item.formType === 'radio-group'">
|
|
|
+ <template v-if="item.type === 'radio-group'">
|
|
|
<el-radio :label="option.label" v-for="option in item.options">{{ option.value }}</el-radio>
|
|
|
</template>
|
|
|
</component>
|
|
|
@@ -228,31 +202,11 @@ const submit = () => {
|
|
|
draggable
|
|
|
:title="dialogTitle"
|
|
|
v-model="dialogVisible"
|
|
|
- width="1000px"
|
|
|
+ width="1200px"
|
|
|
@close="closeDialog"
|
|
|
:close-on-click-modal="false"
|
|
|
>
|
|
|
- <el-form :model="formData" ref="formRef" v-bind="formConfig" class="form">
|
|
|
- <el-row :gutter="20">
|
|
|
- <el-col :span="item.span || 12" v-for="item in formList">
|
|
|
- <el-form-item :label="item.label" :rules="item.rules" :prop="item.name">
|
|
|
- <component
|
|
|
- :is="'el-' + item.formType"
|
|
|
- v-model="formData[item.name]"
|
|
|
- v-bind="formComp"
|
|
|
- :placeholder="item.placeholder || placeholder(item)"
|
|
|
- >
|
|
|
- <template v-if="item.formType === 'radio-group'">
|
|
|
- <el-radio :label="option.label" v-for="option in item.options">{{ option.value }}</el-radio>
|
|
|
- </template>
|
|
|
- <template v-else-if="item.formType === 'select'">
|
|
|
- <el-option :label="option.label" :value="option.value" v-for="option in item.options"></el-option>
|
|
|
- </template>
|
|
|
- </component>
|
|
|
- </el-form-item>
|
|
|
- </el-col>
|
|
|
- </el-row>
|
|
|
- </el-form>
|
|
|
+ <pro-form :form="form" :formData="formData" ref="formRef" :create="crud.create" :update="crud?.update"></pro-form>
|
|
|
|
|
|
<template #footer>
|
|
|
<el-button @click="dialogVisible = false">取消</el-button>
|
|
|
@@ -267,7 +221,4 @@ const submit = () => {
|
|
|
background-color: #f5f7fa;
|
|
|
color: rgb(31, 34, 37);
|
|
|
}
|
|
|
-.form .el-select {
|
|
|
- width: 100%;
|
|
|
-}
|
|
|
</style>
|