|
|
@@ -1,12 +1,13 @@
|
|
|
-<script lang="ts">
|
|
|
-export default {
|
|
|
+<script setup lang="ts">
|
|
|
+defineOptions({
|
|
|
inheritAttrs: false
|
|
|
-}
|
|
|
-</script>
|
|
|
+})
|
|
|
|
|
|
-<script setup lang="ts">
|
|
|
+import { useForm } from '@/hooks/useForm'
|
|
|
+import { useTableQuery } from '@/hooks/useTableQuery'
|
|
|
+import { useTable } from '@/hooks/useTable'
|
|
|
import router from '@/router'
|
|
|
-import { ElMessage, ElMessageBox, type DialogProps } from 'element-plus'
|
|
|
+import type { DialogProps, DrawerProps } from 'element-plus'
|
|
|
import type { BasicForm, BasicFormItem, ICRUD } from '@/types/form'
|
|
|
|
|
|
interface Props {
|
|
|
@@ -14,144 +15,56 @@ interface Props {
|
|
|
pageSize?: number
|
|
|
formConfig: BasicForm
|
|
|
dialogConfig?: DialogProps
|
|
|
+ drawerConfig?: Partial<DrawerProps>
|
|
|
height?: string
|
|
|
cardHeight?: string
|
|
|
showAdd?: boolean
|
|
|
span?: number
|
|
|
+ formMode?: 'dialog' | 'drawer'
|
|
|
+ beforeCreate?: Function
|
|
|
}
|
|
|
|
|
|
const props = withDefaults(defineProps<Props>(), {
|
|
|
pageSize: 12,
|
|
|
showAdd: true,
|
|
|
cardHeight: '206px',
|
|
|
- span: 4
|
|
|
+ span: 4,
|
|
|
+ formMode: 'dialog'
|
|
|
})
|
|
|
|
|
|
const emits = defineEmits(['click-create', 'click-edit'])
|
|
|
|
|
|
// ============== 查询部分开始 ===============
|
|
|
-const query = ref<any>({})
|
|
|
-const searchList = ref<any>([])
|
|
|
-// 构造搜索列表
|
|
|
-const buildSearchList = (item: BasicFormItem) => {
|
|
|
- if (item.search) {
|
|
|
- searchList.value.push(Object.assign({}, item, { props: { ...item.props, disabled: false } }))
|
|
|
- }
|
|
|
- item.children && item.children.forEach(buildSearchList)
|
|
|
-}
|
|
|
-watch(
|
|
|
- () => props.formConfig.formItems,
|
|
|
- val => {
|
|
|
- searchList.value = []
|
|
|
- val.forEach((item: BasicFormItem) => {
|
|
|
- buildSearchList(item)
|
|
|
- })
|
|
|
- },
|
|
|
- { immediate: true }
|
|
|
-)
|
|
|
-
|
|
|
-const handleQuery = () => {
|
|
|
- curPage.value = 1
|
|
|
- getTableData()
|
|
|
-}
|
|
|
-const handleReset = () => {
|
|
|
- query.value = {}
|
|
|
- handleQuery()
|
|
|
-}
|
|
|
+const { query, searchList, handleQuery, handleReset } = useTableQuery(props, emits)
|
|
|
// ============== 查询部分结束 ===============
|
|
|
|
|
|
// ============== 表格部分开始 ===============
|
|
|
-const tableData = ref<any>([])
|
|
|
-const total = ref(0)
|
|
|
-const curPage = ref(1)
|
|
|
-const loading = ref(false)
|
|
|
-
|
|
|
-const getTableData = () => {
|
|
|
- loading.value = true
|
|
|
- props.crud
|
|
|
- ?.getList({
|
|
|
- ...query.value,
|
|
|
- pageSize: props.pageSize,
|
|
|
- pageNo: curPage.value
|
|
|
- })
|
|
|
- .then((res: any) => {
|
|
|
- tableData.value = res.list || res.rows
|
|
|
- total.value = res.total
|
|
|
- })
|
|
|
- .finally(() => {
|
|
|
- loading.value = false
|
|
|
- })
|
|
|
-}
|
|
|
-
|
|
|
-watch(
|
|
|
+const {
|
|
|
+ tableData,
|
|
|
+ formData,
|
|
|
+ getTableData,
|
|
|
+ loading,
|
|
|
+ total,
|
|
|
curPage,
|
|
|
- () => {
|
|
|
- getTableData()
|
|
|
- },
|
|
|
- {
|
|
|
- immediate: true
|
|
|
- }
|
|
|
-)
|
|
|
-
|
|
|
-const refresh = () => {
|
|
|
- curPage.value = 1
|
|
|
- getTableData()
|
|
|
-}
|
|
|
+ formVisible,
|
|
|
+ refresh,
|
|
|
+ handleCreate,
|
|
|
+ handleDelete,
|
|
|
+ handleUpdate,
|
|
|
+ handleView,
|
|
|
+ handleFormSuccess
|
|
|
+} = useTable(props, emits)
|
|
|
|
|
|
// ============== 表格部分结束 ===============
|
|
|
|
|
|
-// ============== crud部分开始 ===============
|
|
|
-const formRoute = ref<any>(props.formConfig.route)
|
|
|
-const handleCreate = () => {
|
|
|
- emits('click-create')
|
|
|
- if (formRoute.value) {
|
|
|
- router.push(formRoute.value)
|
|
|
- } else {
|
|
|
- formData.value = {}
|
|
|
- dialogVisible.value = true
|
|
|
- }
|
|
|
-}
|
|
|
-const handleUpdate = (row: any) => {
|
|
|
- emits('click-edit', row)
|
|
|
- if (formRoute.value) {
|
|
|
- router.push(formRoute.value)
|
|
|
- } else {
|
|
|
- if (props.crud?.getRecord) {
|
|
|
- props.crud.getRecord({ id: row.id }).then((res: any) => {
|
|
|
- formData.value = res.data
|
|
|
- })
|
|
|
- } else {
|
|
|
- formData.value = { ...row }
|
|
|
- }
|
|
|
- dialogVisible.value = true
|
|
|
- }
|
|
|
-}
|
|
|
-const handleDelete = (id: string | number) => {
|
|
|
- ElMessageBox.confirm('您确定要删除该项吗', '提示', {
|
|
|
- type: 'warning'
|
|
|
- }).then(async () => {
|
|
|
- await props.crud?.delete({ id })
|
|
|
- getTableData()
|
|
|
- ElMessage({
|
|
|
- type: 'success',
|
|
|
- message: '删除成功'
|
|
|
- })
|
|
|
- })
|
|
|
-}
|
|
|
-// ============== crud部分结束 ===============
|
|
|
-
|
|
|
-// ============== 表单部分开始 ===============
|
|
|
-const formData = ref<any>({})
|
|
|
-const dialogVisible = ref(false)
|
|
|
-const handleFormSuccess = () => {
|
|
|
- getTableData()
|
|
|
-}
|
|
|
-// ============== 表单部分结束 ===============
|
|
|
+// 构造表单插槽
|
|
|
+const { formSlots } = useForm(props)
|
|
|
|
|
|
defineExpose({
|
|
|
handleCreate,
|
|
|
handleDelete,
|
|
|
handleUpdate,
|
|
|
+ handleView,
|
|
|
refresh
|
|
|
})
|
|
|
</script>
|
|
|
@@ -175,7 +88,7 @@ defineExpose({
|
|
|
<div class="flex flex-col h-full">
|
|
|
<slot name="header"></slot>
|
|
|
|
|
|
- <div class="h-full flex-grow">
|
|
|
+ <div class="h-full flex-grow" v-loading="loading">
|
|
|
<el-row :gutter="10">
|
|
|
<el-col :span="span" v-bind="$attrs" v-if="showAdd" class="mb-10">
|
|
|
<div
|
|
|
@@ -206,16 +119,40 @@ defineExpose({
|
|
|
</div>
|
|
|
</el-card>
|
|
|
|
|
|
- <dialog-form
|
|
|
- v-model="dialogVisible"
|
|
|
- :dialogConfig="dialogConfig"
|
|
|
- :formConfig="formConfig"
|
|
|
- :formData="formData"
|
|
|
- :create="crud.create"
|
|
|
- :update="crud.update"
|
|
|
- @success="handleFormSuccess"
|
|
|
- v-if="dialogVisible"
|
|
|
- />
|
|
|
+ <template v-if="formMode === 'dialog'">
|
|
|
+ <dialog-form
|
|
|
+ v-model="formVisible"
|
|
|
+ v-if="formVisible"
|
|
|
+ :dialogConfig="dialogConfig"
|
|
|
+ :formConfig="formConfig"
|
|
|
+ :formData="formData"
|
|
|
+ :formSlots="formSlots"
|
|
|
+ :create="crud.create"
|
|
|
+ :update="crud.update"
|
|
|
+ @success="handleFormSuccess"
|
|
|
+ >
|
|
|
+ <template #[slot.alias]="slotProps" v-for="slot in formSlots" :key="slot.alias">
|
|
|
+ <slot :name="slot.alias" v-bind="slotProps"></slot>
|
|
|
+ </template>
|
|
|
+ </dialog-form>
|
|
|
+ </template>
|
|
|
+ <template v-else>
|
|
|
+ <drawer-form
|
|
|
+ v-model="formVisible"
|
|
|
+ v-if="formVisible"
|
|
|
+ :drawerConfig="drawerConfig"
|
|
|
+ :formConfig="formConfig"
|
|
|
+ :formData="formData"
|
|
|
+ :formSlots="formSlots"
|
|
|
+ :create="crud.create"
|
|
|
+ :update="crud.update"
|
|
|
+ @success="handleFormSuccess"
|
|
|
+ >
|
|
|
+ <template #[slot.alias]="slotProps" v-for="slot in formSlots" :key="slot.alias">
|
|
|
+ <slot :name="slot.alias" v-bind="slotProps"></slot>
|
|
|
+ </template>
|
|
|
+ </drawer-form>
|
|
|
+ </template>
|
|
|
</div>
|
|
|
</template>
|
|
|
|