|
|
@@ -1,19 +1,38 @@
|
|
|
<script setup lang="ts">
|
|
|
-import { ElMessageBox } from 'element-plus'
|
|
|
+import { ElMessage, ElMessageBox } from 'element-plus'
|
|
|
+import type { PropType } from 'vue'
|
|
|
|
|
|
+interface column {
|
|
|
+ label?: string
|
|
|
+ value: string
|
|
|
+ prop: string
|
|
|
+ formType: string
|
|
|
+ options: Array<any>
|
|
|
+ rules: any
|
|
|
+ search: boolean
|
|
|
+}
|
|
|
+interface CRUD {
|
|
|
+ create: Function
|
|
|
+ update: Function
|
|
|
+ delete: Function
|
|
|
+ getList: Function
|
|
|
+ getRecord: Function
|
|
|
+}
|
|
|
const props = defineProps({
|
|
|
- request: {
|
|
|
- type: Function,
|
|
|
- default: () => {}
|
|
|
- },
|
|
|
+ crud: Object as PropType<CRUD>,
|
|
|
pageSize: {
|
|
|
type: Number,
|
|
|
default: 10
|
|
|
+ },
|
|
|
+ columns: {
|
|
|
+ type: Array as PropType<column[]>,
|
|
|
+ default: () => []
|
|
|
}
|
|
|
})
|
|
|
|
|
|
// ============== 查询部分开始 ===============
|
|
|
-const query = ref({})
|
|
|
+const query = ref<any>({})
|
|
|
+const searchList = computed(() => props.columns.filter(item => item.search))
|
|
|
const handleQuery = () => {
|
|
|
curPage.value = 1
|
|
|
getTableData()
|
|
|
@@ -29,8 +48,8 @@ const total = ref(0)
|
|
|
const curPage = ref(1)
|
|
|
|
|
|
const getTableData = () => {
|
|
|
- props
|
|
|
- .request({
|
|
|
+ props.crud
|
|
|
+ ?.getList({
|
|
|
...query.value,
|
|
|
pageSize: props.pageSize,
|
|
|
page: curPage.value
|
|
|
@@ -49,29 +68,84 @@ const pageChange = () => {
|
|
|
|
|
|
// ============== crud部分开始 ===============
|
|
|
const handleCreate = () => {
|
|
|
- curPage.value = 1
|
|
|
- getTableData()
|
|
|
+ dialogTitle.value = '新建'
|
|
|
+ dialogVisible.value = true
|
|
|
}
|
|
|
-const handleUpdate = () => {
|
|
|
- query.value = {}
|
|
|
+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
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ formData.value = row
|
|
|
+ }
|
|
|
}
|
|
|
-const handleDelete = () => {
|
|
|
+const handleDelete = (id: string | number) => {
|
|
|
ElMessageBox.confirm('您确定要删除该项吗', '提示', {
|
|
|
type: 'warning'
|
|
|
- }).then(() => {})
|
|
|
+ }).then(async () => {
|
|
|
+ const res = await props.crud?.delete(id)
|
|
|
+ if (res.code === 0) {
|
|
|
+ ElMessage({
|
|
|
+ type: 'success',
|
|
|
+ message: '删除成功'
|
|
|
+ })
|
|
|
+ }
|
|
|
+ })
|
|
|
}
|
|
|
const handlePatchDelete = () => {}
|
|
|
// ============== crud部分结束 ===============
|
|
|
+
|
|
|
+const dialogTitle = ref('新建')
|
|
|
+const dialogVisible = ref(false)
|
|
|
+const beforeClose = () => {
|
|
|
+ console.log('object')
|
|
|
+ formData.value = {}
|
|
|
+}
|
|
|
+
|
|
|
+const formData = ref<any>({})
|
|
|
+const formRef = ref()
|
|
|
+
|
|
|
+const submit = () => {
|
|
|
+ let res, message
|
|
|
+ formRef.value.validate(async (valid: boolean) => {
|
|
|
+ if (valid) {
|
|
|
+ if (formData.id) {
|
|
|
+ res = props.crud?.update(formData.value)
|
|
|
+ message = '新建成功'
|
|
|
+ } else {
|
|
|
+ res = props.crud?.create(formData.value)
|
|
|
+ message = '修改成功'
|
|
|
+ }
|
|
|
+
|
|
|
+ if (res.code === 0) {
|
|
|
+ ElMessage({
|
|
|
+ type: 'success',
|
|
|
+ message
|
|
|
+ })
|
|
|
+ dialogVisible.value = false
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+}
|
|
|
</script>
|
|
|
|
|
|
<template>
|
|
|
- <div class="flex flex-col" style="height: calc(100vh - 100px)">
|
|
|
+ <div class="flex flex-col" style="height: calc(100vh - 60px - var(--main-padding) * 2)">
|
|
|
<el-card class="mb-4" shadow="never">
|
|
|
<el-form :inline="true">
|
|
|
- <slot name="queryBar" :query="query"></slot>
|
|
|
+ <el-form-item :label="item.label" v-for="item in searchList">
|
|
|
+ <component :is="'el-' + item.formType" v-model="query[item.prop]">
|
|
|
+ <template v-if="item.formType === 'radio-group'">
|
|
|
+ <el-radio :label="option.label" v-for="option in item.options">{{ option.value }}</el-radio>
|
|
|
+ </template>
|
|
|
+ </component>
|
|
|
+ </el-form-item>
|
|
|
<el-form-item>
|
|
|
- <el-button type="primary" icon="search" @click="handleQuery">查询</el-button>
|
|
|
- <el-button icon="i-ep-refresh" @click="handleReset">重置</el-button>
|
|
|
+ <el-button type="primary" @click="handleQuery">查询</el-button>
|
|
|
+ <el-button @click="handleReset">重置</el-button>
|
|
|
</el-form-item>
|
|
|
</el-form>
|
|
|
</el-card>
|
|
|
@@ -87,9 +161,9 @@ const handlePatchDelete = () => {}
|
|
|
<el-table class="flex-grow-1 h-full" :data="tableData">
|
|
|
<slot name="table"></slot>
|
|
|
<el-table-column fixed="right" label="操作" width="120">
|
|
|
- <template #default>
|
|
|
- <el-button link type="primary" size="small" @click="handleUpdate">编辑</el-button>
|
|
|
- <el-button link type="danger" size="small" @click="handleDelete">删除</el-button>
|
|
|
+ <template #default="{ row }">
|
|
|
+ <el-button link type="primary" size="small" @click="handleUpdate(row)">编辑</el-button>
|
|
|
+ <el-button link type="danger" size="small" @click="handleDelete(row.id)">删除</el-button>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
</el-table>
|
|
|
@@ -105,6 +179,29 @@ const handlePatchDelete = () => {}
|
|
|
</div>
|
|
|
</div>
|
|
|
</el-card>
|
|
|
+
|
|
|
+ <el-dialog draggable :title="dialogTitle" v-model="dialogVisible" width="1000px" :before-close="beforeClose">
|
|
|
+ <el-form :model="formData" ref="formRef" label-width="100px">
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <el-col :span="12" v-for="item in columns">
|
|
|
+ <el-form-item :label="item.label" :rules="item.rules" :prop="item.prop">
|
|
|
+ <component :is="'el-' + item.formType" v-model="formData[item.prop]">
|
|
|
+ <template v-if="item.formType === 'radio-group'">
|
|
|
+ <el-radio :label="option.label" v-for="option in item.options">{{ option.value }}</el-radio>
|
|
|
+ </template>
|
|
|
+ </component>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </el-form>
|
|
|
+
|
|
|
+ <template #footer>
|
|
|
+ <span>
|
|
|
+ <el-button @click="dialogVisible = false">取消</el-button>
|
|
|
+ <el-button type="primary" @click="submit">保存</el-button>
|
|
|
+ </span>
|
|
|
+ </template>
|
|
|
+ </el-dialog>
|
|
|
</div>
|
|
|
</template>
|
|
|
|