Browse Source

Merge remote-tracking branch 'origin/master'

heguanxun 1 year ago
parent
commit
784fc3d382
40 changed files with 2126 additions and 1211 deletions
  1. 34 0
      snowy-admin-web/src/api/biz/demo1Api.js
  2. 12 6
      snowy-admin-web/src/api/biz/demo2Api.js
  3. 0 28
      snowy-admin-web/src/api/biz/demoApi.js
  4. 0 97
      snowy-admin-web/src/views/biz/demo/form.vue
  5. 0 145
      snowy-admin-web/src/views/biz/demo/index.vue
  6. 150 0
      snowy-admin-web/src/views/biz/demo1/detail.vue
  7. 315 0
      snowy-admin-web/src/views/biz/demo1/index.vue
  8. 0 91
      snowy-admin-web/src/views/biz/demo2/detail.vue
  9. 161 0
      snowy-admin-web/src/views/biz/demo2/form.vue
  10. 112 49
      snowy-admin-web/src/views/biz/demo2/index.vue
  11. 409 376
      snowy-admin-web/src/views/gen/config.vue
  12. 0 123
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo/controller/DemoController.java
  13. 0 59
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo/entity/Demo.java
  14. 0 103
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo/service/impl/DemoServiceImpl.java
  15. 173 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo1/controller/Demo1Controller.java
  16. 158 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo1/entity/Demo1.java
  17. 5 5
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo/enums/DemoEnum.java
  18. 5 5
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo/mapper/DemoMapper.java
  19. 1 1
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo/mapper/mapping/DemoMapper.xml
  20. 44 4
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo/param/DemoAddParam.java
  21. 44 4
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo/param/DemoEditParam.java
  22. 4 4
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo/param/DemoIdParam.java
  23. 40 4
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo/param/DemoPageParam.java
  24. 27 27
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo/service/DemoService.java
  25. 124 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo1/service/impl/Demo1ServiceImpl.java
  26. 72 22
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo2/controller/Demo2Controller.java
  27. 102 3
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo2/entity/Demo2.java
  28. 2 2
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo2/enums/Demo2Enum.java
  29. 2 2
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo2/mapper/Demo2Mapper.java
  30. 52 3
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo2/param/Demo2AddParam.java
  31. 52 3
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo2/param/Demo2EditParam.java
  32. 2 2
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo2/param/Demo2IdParam.java
  33. 2 14
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo2/param/Demo2PageParam.java
  34. 14 14
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo2/service/Demo2Service.java
  35. 3 12
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo2/service/impl/Demo2ServiceImpl.java
  36. 1 1
      snowy-plugin/snowy-plugin-gen/src/main/resources/frontend/Api.js.btl
  37. 1 1
      snowy-plugin/snowy-plugin-gen/src/main/resources/frontend/detail.vue.btl
  38. 1 1
      snowy-plugin/snowy-plugin-gen/src/main/resources/frontend/form.vue.btl
  39. 1 0
      snowy-plugin/snowy-plugin-gen/src/main/resources/frontend/index.vue.btl
  40. 1 0
      snowy-plugin/snowy-plugin-gen/src/main/resources/frontend/index_inside.vue.btl

+ 34 - 0
snowy-admin-web/src/api/biz/demo1Api.js

@@ -0,0 +1,34 @@
+import { baseRequest } from '@/utils/request'
+
+const request = (url, ...arg) => baseRequest(`/biz/demo1/` + url, ...arg)
+
+/**
+ * 内嵌表单Api接口管理器
+ *
+ * @author 曹钊瑞
+ * @date  2024/07/02 18:06
+ **/
+export default {
+	// 获取内嵌表单分页
+	demo1Page(data) {
+		return request('page', data, 'get')
+	},
+	// 提交内嵌表单表单 edit为true时为编辑,默认为新增
+	demo1SubmitForm(data, edit = false) {
+		return request(edit ? 'edit' : 'add', data)
+	},
+	// 删除内嵌表单
+	demo1Delete(data) {
+		return request('delete', data)
+	},
+	// 导出内嵌表单
+    demo1Export(data) {
+        return request('export', data, 'get', {
+            responseType: 'blob'
+        })
+    },
+	// 获取内嵌表单详情
+	demo1Detail(data) {
+		return request('detail', data, 'get')
+	}
+}

+ 12 - 6
snowy-admin-web/src/api/biz/demo2Api.js

@@ -3,25 +3,31 @@ import { baseRequest } from '@/utils/request'
 const request = (url, ...arg) => baseRequest(`/biz/demo2/` + url, ...arg)
 
 /**
- * 例子2Api接口管理器
+ * 弹窗表单Api接口管理器
  *
  * @author 曹钊瑞
- * @date  2024/07/01 17:47
+ * @date  2024/07/02 18:06
  **/
 export default {
-	// 获取例子2分页
+	// 获取弹窗表单分页
 	demo2Page(data) {
 		return request('page', data, 'get')
 	},
-	// 提交例子2表单 edit为true时为编辑,默认为新增
+	// 提交弹窗表单表单 edit为true时为编辑,默认为新增
 	demo2SubmitForm(data, edit = false) {
 		return request(edit ? 'edit' : 'add', data)
 	},
-	// 删除例子2
+	// 删除弹窗表单
 	demo2Delete(data) {
 		return request('delete', data)
 	},
-	// 获取例子2详情
+	// 导出弹窗表单
+    demo2Export(data) {
+        return request('export', data, 'get', {
+            responseType: 'blob'
+        })
+    },
+	// 获取弹窗表单详情
 	demo2Detail(data) {
 		return request('detail', data, 'get')
 	}

+ 0 - 28
snowy-admin-web/src/api/biz/demoApi.js

@@ -1,28 +0,0 @@
-import { baseRequest } from '@/utils/request'
-
-const request = (url, ...arg) => baseRequest(`/biz/demo/` + url, ...arg)
-
-/**
- * 例子Api接口管理器
- *
- * @author 曹钊瑞
- * @date  2024/07/01 17:46
- **/
-export default {
-	// 获取例子分页
-	demoPage(data) {
-		return request('page', data, 'get')
-	},
-	// 提交例子表单 edit为true时为编辑,默认为新增
-	demoSubmitForm(data, edit = false) {
-		return request(edit ? 'edit' : 'add', data)
-	},
-	// 删除例子
-	demoDelete(data) {
-		return request('delete', data)
-	},
-	// 获取例子详情
-	demoDetail(data) {
-		return request('detail', data, 'get')
-	}
-}

+ 0 - 97
snowy-admin-web/src/views/biz/demo/form.vue

@@ -1,97 +0,0 @@
-<template>
-	<xn-form-container
-		:title="formData.id ? '编辑例子' : '增加例子'"
-		:width="700"
-		v-model:open="open"
-		:destroy-on-close="true"
-		@close="onClose"
-	>
-		<a-form ref="formRef" :model="formData" :rules="formRules" layout="vertical">
-			<a-row :gutter="16">
-				<a-col :span="12">
-					<a-form-item label="NAME:" name="name">
-						<a-input v-model:value="formData.name" placeholder="请输入NAME" allow-clear />
-					</a-form-item>
-				</a-col>
-				<a-col :span="12">
-					<a-form-item label="AGE:" name="age">
-						<a-input v-model:value="formData.age" placeholder="请输入AGE" allow-clear />
-					</a-form-item>
-				</a-col>
-				<a-col :span="12">
-					<a-form-item label="SEX:" name="sex">
-						<a-input v-model:value="formData.sex" placeholder="请输入SEX" allow-clear />
-					</a-form-item>
-				</a-col>
-				<a-col :span="12">
-					<a-form-item label="REMARK:" name="remark">
-						<a-input v-model:value="formData.remark" placeholder="请输入REMARK" allow-clear />
-					</a-form-item>
-				</a-col>
-			</a-row>
-		</a-form>
-		<template #footer>
-			<a-button style="margin-right: 8px" @click="onClose">关闭</a-button>
-			<a-popconfirm title="请确认是否保存?" @confirm="onSubmit">
-                <a-button type="primary" :loading="submitLoading">保存</a-button>
-            </a-popconfirm>
-		</template>
-	</xn-form-container>
-</template>
-
-<script setup name="demoForm">
-	import { cloneDeep } from 'lodash-es'
-	import { required } from '@/utils/formRules'
-	import demoApi from '@/api/biz/demoApi'
-	// 抽屉状态
-	const open = ref(false)
-	const emit = defineEmits({ successful: null })
-	const formRef = ref()
-	// 表单数据
-	const formData = ref({})
-	const submitLoading = ref(false)
-
-	// 打开抽屉
-	const onOpen = (record) => {
-		open.value = true
-		if (record) {
-			let recordData = cloneDeep(record)
-			formData.value = Object.assign({}, recordData)
-		}
-	}
-	// 关闭抽屉
-	const onClose = () => {
-		formRef.value.resetFields()
-		formData.value = {}
-		open.value = false
-	}
-	// 默认要校验的
-	const formRules = {
-		name: [required('请输入NAME')],
-		age: [required('请输入AGE')],
-		sex: [required('请输入SEX')],
-	}
-	// 验证并提交数据
-	const onSubmit = () => {
-		formRef.value
-			.validate()
-			.then(() => {
-				submitLoading.value = true
-				const formDataParam = cloneDeep(formData.value)
-				demoApi
-					.demoSubmitForm(formDataParam, formDataParam.id)
-					.then(() => {
-						onClose()
-						emit('successful')
-					})
-					.finally(() => {
-						submitLoading.value = false
-					})
-			})
-			.catch(() => {})
-	}
-	// 抛出函数
-	defineExpose({
-		onOpen
-	})
-</script>

+ 0 - 145
snowy-admin-web/src/views/biz/demo/index.vue

@@ -1,145 +0,0 @@
-<template>
-	<a-card :bordered="false">
-		<a-form ref="searchFormRef" name="advanced_search" :model="searchFormState" class="ant-advanced-search-form">
-			<a-row :gutter="24">
-				<a-col :span="6">
-					<a-form-item label="NAME" name="name">
-						<a-input v-model:value="searchFormState.name" placeholder="请输入NAME" />
-					</a-form-item>
-				</a-col>
-				<a-col :span="6">
-					<a-form-item label="AGE" name="age">
-						<a-input v-model:value="searchFormState.age" placeholder="请输入AGE" />
-					</a-form-item>
-				</a-col>
-				<a-col :span="6">
-					<a-form-item label="SEX" name="sex">
-						<a-input v-model:value="searchFormState.sex" placeholder="请输入SEX" />
-					</a-form-item>
-				</a-col>
-				<a-col :span="6">
-					<a-button type="primary" @click="tableRef.refresh()">查询</a-button>
-					<a-button style="margin: 0 8px" @click="reset">重置</a-button>
-				</a-col>
-			</a-row>
-		</a-form>
-		<s-table
-			ref="tableRef"
-			:columns="columns"
-			:data="loadData"
-			:alert="options.alert.show"
-			bordered
-			:row-key="(record) => record.id"
-			:tool-config="toolConfig"
-			:row-selection="options.rowSelection"
-		>
-			<template #operator class="table-operator">
-				<a-space>
-					<a-button type="primary" @click="formRef.onOpen()" v-if="hasPerm('demoAdd')">
-						<template #icon><plus-outlined /></template>
-						新增
-					</a-button>
-					<xn-batch-delete
-						v-if="hasPerm('demoBatchDelete')"
-						:selectedRowKeys="selectedRowKeys"
-						@batchDelete="deleteBatchDemo"
-					/>
-				</a-space>
-			</template>
-			<template #bodyCell="{ column, record }">
-				<template v-if="column.dataIndex === 'action'">
-					<a-space>
-						<a @click="formRef.onOpen(record)" v-if="hasPerm('demoEdit')">编辑</a>
-						<a-divider type="vertical" v-if="hasPerm(['demoEdit', 'demoDelete'], 'and')" />
-						<a-popconfirm title="确定要删除吗?" @confirm="deleteDemo(record)">
-							<a-button type="link" danger size="small" v-if="hasPerm('demoDelete')">删除</a-button>
-						</a-popconfirm>
-					</a-space>
-				</template>
-			</template>
-		</s-table>
-	</a-card>
-	<Form ref="formRef" @successful="tableRef.refresh()" />
-</template>
-
-<script setup name="demo">
-	import { cloneDeep } from 'lodash-es'
-	import Form from './form.vue'
-	import demoApi from '@/api/biz/demoApi'
-	const searchFormState = ref({})
-	const searchFormRef = ref()
-	const tableRef = ref()
-	const formRef = ref()
-	const toolConfig = { refresh: true, height: true, columnSetting: true, striped: false }
-	const columns = [
-		{
-			title: 'NAME',
-			dataIndex: 'name'
-		},
-		{
-			title: 'AGE',
-			dataIndex: 'age'
-		},
-		{
-			title: 'SEX',
-			dataIndex: 'sex'
-		},
-		{
-			title: 'REMARK',
-			dataIndex: 'remark'
-		},
-	]
-	// 操作栏通过权限判断是否显示
-	if (hasPerm(['demoEdit', 'demoDelete'])) {
-		columns.push({
-			title: '操作',
-			dataIndex: 'action',
-			align: 'center',
-			width: 150
-		})
-	}
-	const selectedRowKeys = ref([])
-	// 列表选择配置
-	const options = {
-		// columns数字类型字段加入 needTotal: true 可以勾选自动算账
-		alert: {
-			show: true,
-			clear: () => {
-				selectedRowKeys.value = ref([])
-			}
-		},
-		rowSelection: {
-			onChange: (selectedRowKey, selectedRows) => {
-				selectedRowKeys.value = selectedRowKey
-			}
-		}
-	}
-	const loadData = (parameter) => {
-		const searchFormParam = cloneDeep(searchFormState.value)
-		return demoApi.demoPage(Object.assign(parameter, searchFormParam)).then((data) => {
-			return data
-		})
-	}
-	// 重置
-	const reset = () => {
-		searchFormRef.value.resetFields()
-		tableRef.value.refresh(true)
-	}
-	// 删除
-	const deleteDemo = (record) => {
-		let params = [
-			{
-				id: record.id
-			}
-		]
-		demoApi.demoDelete(params).then(() => {
-			tableRef.value.refresh(true)
-		})
-	}
-	// 批量删除
-	const deleteBatchDemo = (params) => {
-		demoApi.demoDelete(params).then(() => {
-			tableRef.value.clearRefreshSelected()
-		})
-	}
-</script>

+ 150 - 0
snowy-admin-web/src/views/biz/demo1/detail.vue

@@ -0,0 +1,150 @@
+<template>
+    <a-card :bordered="false">
+		<a-page-header
+            :title="formData.id ? '编辑内嵌表单' : '新增内嵌表单'"
+			@back="onClose"
+		>
+			<template #extra>
+				<a-button style="margin-right: 8px" @click="onClose">关闭</a-button>
+				<a-popconfirm title="请确认是否保存?" @confirm="onSubmit" v-if="!isView">
+                    <a-button type="primary" :loading="submitLoading">保存</a-button>
+                </a-popconfirm>
+			</template>
+		</a-page-header>
+		<a-form ref="formRef" :model="formData" :rules="formRules" layout="vertical">
+            <a-row :gutter="16">
+                <a-col :span="12">
+                    <a-form-item label="NAME:" name="name">
+                        <a-input v-model:value="formData.name" :disabled="isView" placeholder="请输入NAME" allow-clear />
+                    </a-form-item>
+                </a-col>
+                <a-col :span="12">
+                    <a-form-item label="AGE:" name="age">
+                        <a-input v-model:value="formData.age" :disabled="isView" placeholder="请输入AGE" allow-clear />
+                    </a-form-item>
+                </a-col>
+                <a-col :span="12">
+                    <a-form-item label="SEX:" name="sex">
+                        <a-select v-model:value="formData.sex" :disabled="isView" placeholder="请选择SEX" :options="sexOptions" />
+                    </a-form-item>
+                </a-col>
+                <a-col :span="12">
+                    <a-form-item label="REMARK:" name="remark">
+                        <a-input v-model:value="formData.remark" :disabled="isView" placeholder="请输入REMARK" allow-clear />
+                    </a-form-item>
+                </a-col>
+                <a-col :span="12">
+                    <a-form-item label="P1:" name="p1">
+                        <a-input v-model:value="formData.p1" :disabled="isView" placeholder="请输入P1" allow-clear />
+                    </a-form-item>
+                </a-col>
+                <a-col :span="12">
+                    <a-form-item label="P2:" name="p2">
+                        <a-input v-model:value="formData.p2" :disabled="isView" placeholder="请输入P2" allow-clear />
+                    </a-form-item>
+                </a-col>
+                <a-col :span="12">
+                    <a-form-item label="P3:" name="p3">
+                        <a-input v-model:value="formData.p3" :disabled="isView" placeholder="请输入P3" allow-clear />
+                    </a-form-item>
+                </a-col>
+                <a-col :span="12">
+                    <a-form-item label="P4:" name="p4">
+                        <a-input v-model:value="formData.p4" :disabled="isView" placeholder="请输入P4" allow-clear />
+                    </a-form-item>
+                </a-col>
+                <a-col :span="12">
+                    <a-form-item label="P5:" name="p5">
+                        <a-input v-model:value="formData.p5" :disabled="isView" placeholder="请输入P5" allow-clear />
+                    </a-form-item>
+                </a-col>
+                <a-col :span="12">
+                    <a-form-item label="P6:" name="p6">
+                        <a-input v-model:value="formData.p6" :disabled="isView" placeholder="请输入P6" allow-clear />
+                    </a-form-item>
+                </a-col>
+                <a-col :span="12">
+                    <a-form-item label="P7:" name="p7">
+                        <a-input v-model:value="formData.p7" :disabled="isView" placeholder="请输入P7" allow-clear />
+                    </a-form-item>
+                </a-col>
+                <a-col :span="12">
+                    <a-form-item label="P8:" name="p8">
+                        <a-input v-model:value="formData.p8" :disabled="isView" placeholder="请输入P8" allow-clear />
+                    </a-form-item>
+                </a-col>
+                <a-col :span="12">
+                    <a-form-item label="P9:" name="p9">
+                        <a-input v-model:value="formData.p9" :disabled="isView" placeholder="请输入P9" allow-clear />
+                    </a-form-item>
+                </a-col>
+                <a-col :span="12">
+                    <a-form-item label="P10:" name="p10">
+                        <a-input v-model:value="formData.p10" :disabled="isView" placeholder="请输入P10" allow-clear />
+                    </a-form-item>
+                </a-col>
+            </a-row>
+        </a-form>
+	</a-card>
+</template>
+
+<script setup name="demo1Detail">
+	import tool from '@/utils/tool'
+	import { cloneDeep } from 'lodash-es'
+	import { required } from '@/utils/formRules'
+	import demo1Api from '@/api/biz/demo1Api'
+	// 抽屉状态
+	const emit = defineEmits({ successful: null })
+	const formRef = ref()
+	// 表单数据
+	const formData = ref({})
+	const submitLoading = ref(false)
+	const isView = ref(false)
+	const sexOptions = ref([])
+
+	// 打开抽屉
+	const onOpen = (record, view = false) => {
+	    isView.value = view
+		if (record) {
+			let recordData = cloneDeep(record)
+			formData.value = Object.assign({}, recordData)
+		}
+		sexOptions.value = tool.dictList('GENDER')
+	}
+	// 关闭抽屉
+	const onClose = () => {
+		formRef.value.resetFields()
+		formData.value = {}
+		isView.value = true
+		emit('onClose')
+	}
+	// 默认要校验的
+	const formRules = {
+		name: [required('请输入NAME')],
+		age: [required('请输入AGE')],
+		sex: [required('请输入SEX')],
+	}
+	// 验证并提交数据
+	const onSubmit = () => {
+		formRef.value
+			.validate()
+			.then(() => {
+				submitLoading.value = true
+				const formDataParam = cloneDeep(formData.value)
+				demo1Api
+					.demo1SubmitForm(formDataParam, formDataParam.id)
+					.then(() => {
+						onClose()
+						emit('successful')
+					})
+					.finally(() => {
+						submitLoading.value = false
+					})
+			})
+			.catch(() => {})
+	}
+	// 抛出函数
+	defineExpose({
+		onOpen
+	})
+</script>

+ 315 - 0
snowy-admin-web/src/views/biz/demo1/index.vue

@@ -0,0 +1,315 @@
+<template>
+	<a-card :bordered="false" v-if="indexShow">
+		<a-form ref="searchFormRef" name="advanced_search" :model="searchFormState" class="ant-advanced-search-form">
+			<a-row :gutter="24">
+				<a-col :span="6">
+					<a-form-item label="NAME" name="name">
+						<a-input v-model:value="searchFormState.name" placeholder="请输入NAME" />
+					</a-form-item>
+				</a-col>
+				<a-col :span="6">
+					<a-form-item label="AGE" name="age">
+						<a-input v-model:value="searchFormState.age" placeholder="请输入AGE" />
+					</a-form-item>
+				</a-col>
+				<a-col :span="6">
+					<a-form-item label="SEX" name="sex">
+						<a-select v-model:value="searchFormState.sex" placeholder="请选择SEX" :options="sexOptions" />
+					</a-form-item>
+				</a-col>
+				<a-col :span="6" v-show="advanced">
+					<a-form-item label="REMARK" name="remark">
+						<a-input v-model:value="searchFormState.remark" placeholder="请输入REMARK" />
+					</a-form-item>
+				</a-col>
+				<a-col :span="6" v-show="advanced">
+					<a-form-item label="P1" name="p1">
+						<a-input v-model:value="searchFormState.p1" placeholder="请输入P1" />
+					</a-form-item>
+				</a-col>
+				<a-col :span="6" v-show="advanced">
+					<a-form-item label="P2" name="p2">
+						<a-input v-model:value="searchFormState.p2" placeholder="请输入P2" />
+					</a-form-item>
+				</a-col>
+				<a-col :span="6" v-show="advanced">
+					<a-form-item label="P3" name="p3">
+						<a-input v-model:value="searchFormState.p3" placeholder="请输入P3" />
+					</a-form-item>
+				</a-col>
+				<a-col :span="6" v-show="advanced">
+					<a-form-item label="P4" name="p4">
+						<a-input v-model:value="searchFormState.p4" placeholder="请输入P4" />
+					</a-form-item>
+				</a-col>
+				<a-col :span="6" v-show="advanced">
+					<a-form-item label="CREATE_TIME" name="createTime">
+						<a-range-picker v-model:value="searchFormState.createTime" show-time />
+					</a-form-item>
+				</a-col>
+				<a-col :span="6" v-show="advanced">
+					<a-form-item label="UPDATE_TIME" name="updateTime">
+						<a-range-picker v-model:value="searchFormState.updateTime" show-time />
+					</a-form-item>
+				</a-col>
+				<a-col :span="6">
+					<a-button type="primary" @click="onSearch()">查询</a-button>
+					<a-button style="margin: 0 8px" @click="reset">重置</a-button>
+					<a @click="toggleAdvanced" style="margin-left: 8px">
+						{{ advanced ? '收起' : '展开' }}
+						<component :is="advanced ? 'up-outlined' : 'down-outlined'"/>
+					</a>
+				</a-col>
+			</a-row>
+		</a-form>
+		<s-table
+			ref="tableRef"
+			:columns="columns"
+			:data="loadData"
+			:alert="options.alert.show"
+			bordered
+			:row-key="(record) => record.id"
+			:tool-config="toolConfig"
+			:row-selection="options.rowSelection"
+			v-model:filterParam="filterParam"
+			:scroll="{ x: 2000 }"
+		>
+			<template #operator class="table-operator">
+				<a-space>
+					<a-button type="primary" @click="onDetail()" v-if="hasPerm('demo1Add')">
+						<template #icon><plus-outlined /></template>
+						新增
+					</a-button>
+					<xn-batch-delete
+						v-if="hasPerm('demo1Delete')"
+						:selectedRowKeys="selectedRowKeys"
+						@batchDelete="deleteBatchDemo1"
+					/>
+					<a-button @click="onExport" v-if="hasPerm('demo1BatchExport')">
+                        <template #icon><export-outlined /></template>
+                        批量导出
+                    </a-button>
+				</a-space>
+			</template>
+			<template #bodyCell="{ column, record }">
+				<template v-if="column.dataIndex === 'sex'">
+					{{ $TOOL.dictTypeData('GENDER', record.sex) }}
+				</template>
+				<template v-if="column.dataIndex === 'action'">
+					<a-space>
+					    <a @click="onDetail(record, true)" v-if="hasPerm('demo1View')">查看</a>
+                        <a-divider type="vertical" v-if="hasPerm('demo1View') && hasPerm(['demo1Edit', 'demo1Delete'], 'or')" />
+						<a @click="onDetail(record)" v-if="hasPerm('demo1Edit')">编辑</a>
+						<a-divider type="vertical" v-if="hasPerm(['demo1Edit', 'demo1Delete'], 'and')" />
+						<a-popconfirm title="确定要删除吗?" @confirm="deleteDemo1(record)">
+							<a-button type="link" danger size="small" v-if="hasPerm('demo1Delete')">删除</a-button>
+						</a-popconfirm>
+					</a-space>
+				</template>
+			</template>
+		</s-table>
+	</a-card>
+	<Detail v-else ref="detailRef" @onClose="indexShow = true" @successful="onSearch()" />
+</template>
+
+<script setup name="demo1">
+	import tool from '@/utils/tool'
+	import { cloneDeep } from 'lodash-es'
+	import Detail from './detail.vue'
+	import demo1Api from '@/api/biz/demo1Api'
+	import downloadUtil from "@/utils/downloadUtil";
+    const { proxy } = getCurrentInstance()
+	const searchFormState = ref({})
+	const searchFormStateReal = ref({}) // 点击搜索后备份的查询参数
+	const searchFormRef = ref()
+	const tableRef = ref()
+	const filterParam = ref({})
+	const detailRef = ref()
+	const indexShow = ref(true)
+	const toolConfig = { refresh: true, height: true, columnSetting: true, striped: false }
+	// 查询区域显示更多控制
+	const advanced = ref(false)
+	const toggleAdvanced = () => {
+		advanced.value = !advanced.value
+	}
+	const columns = [
+		{
+			title: 'NAME',
+			dataIndex: 'name',
+            sorter: true,
+            fixed: 'left',
+		},
+		{
+			title: 'AGE',
+			dataIndex: 'age',
+            sorter: true,
+		},
+		{
+			title: 'SEX',
+			dataIndex: 'sex',
+		},
+		{
+			title: 'REMARK',
+			dataIndex: 'remark',
+		},
+		{
+			title: 'P1',
+			dataIndex: 'p1',
+		},
+		{
+			title: 'P2',
+			dataIndex: 'p2',
+		},
+		{
+			title: 'P3',
+			dataIndex: 'p3',
+		},
+		{
+			title: 'P4',
+			dataIndex: 'p4',
+		},
+		{
+			title: 'P5',
+			dataIndex: 'p5',
+		},
+		{
+			title: 'P6',
+			dataIndex: 'p6',
+		},
+		{
+			title: 'P7',
+			dataIndex: 'p7',
+		},
+		{
+			title: 'P8',
+			dataIndex: 'p8',
+		},
+		{
+			title: 'P9',
+			dataIndex: 'p9',
+		},
+		{
+			title: 'P10',
+			dataIndex: 'p10',
+		},
+		{
+			title: 'CREATE_TIME',
+			dataIndex: 'createTime',
+            sorter: true,
+		},
+		{
+			title: 'CREATE_BY',
+			dataIndex: 'createBy',
+		},
+		{
+			title: 'UPDATE_TIME',
+			dataIndex: 'updateTime',
+            sorter: true,
+            fixed: 'right',
+		},
+		{
+			title: 'UPDATE_BY',
+			dataIndex: 'updateBy',
+		},
+	]
+	// 操作栏通过权限判断是否显示
+	if (hasPerm(['demo1Edit', 'demo1Delete'])) {
+		columns.push({
+			title: '操作',
+			dataIndex: 'action',
+			align: 'center',
+			width: 200,
+			fixed: 'right',
+		})
+	}
+	const selectedRowKeys = ref([])
+	// 列表选择配置
+	const options = {
+		// columns数字类型字段加入 needTotal: true 可以勾选自动算账
+		alert: {
+			show: true,
+			clear: () => {
+				selectedRowKeys.value = ref([])
+			}
+		},
+		rowSelection: {
+			onChange: (selectedRowKey, selectedRows) => {
+				selectedRowKeys.value = selectedRowKey
+			}
+		}
+	}
+	const loadData = (parameter) => {
+        // createTime范围查询条件重载
+        if (searchFormStateReal.value.createTime) {
+            searchFormStateReal.value.startCreateTime = searchFormStateReal.value.createTime[0]
+            searchFormStateReal.value.endCreateTime = searchFormStateReal.value.createTime[1]
+            delete searchFormStateReal.value.createTime
+        }
+        // updateTime范围查询条件重载
+        if (searchFormStateReal.value.updateTime) {
+            searchFormStateReal.value.startUpdateTime = searchFormStateReal.value.updateTime[0]
+            searchFormStateReal.value.endUpdateTime = searchFormStateReal.value.updateTime[1]
+            delete searchFormStateReal.value.updateTime
+        }
+        return demo1Api.demo1Page(Object.assign(parameter, searchFormStateReal.value)).then((data) => {
+            return data
+        })
+    }
+    // 搜索同时备份参数
+    const onSearch = (parameter) => {
+        searchFormStateReal.value = cloneDeep(searchFormState.value)
+        tableRef.value.refresh(parameter)
+    }
+    // 重置
+    const reset = () => {
+        searchFormRef.value.resetFields()
+        onSearch(true)
+    }
+	// 删除
+	const deleteDemo1 = (record) => {
+		let params = [
+			{
+				id: record.id
+			}
+		]
+		demo1Api.demo1Delete(params).then(() => {
+			tableRef.value.refresh(true)
+		})
+	}
+	// 批量删除
+	const deleteBatchDemo1 = (params) => {
+		demo1Api.demo1Delete(params).then(() => {
+			tableRef.value.clearRefreshSelected()
+		})
+	}
+	// 批量导出
+    const onExport = () => {
+        const params = {
+            ...filterParam.value
+        }
+        if (selectedRowKeys.value.length > 0) {
+            params.ids = selectedRowKeys.value
+        } else {
+            Object.entries(searchFormStateReal.value).forEach(([key, value]) => {
+                console.log(key)
+                if (proxy.$util.isValue(value)) {
+                    params[key] = value
+                }
+            })
+        }
+        demo1Api.demo1Export(params).then((res) => {
+            downloadUtil.resultDownload(res)
+            tableRef.value.clearSelected()
+        })
+    }
+	// 切换至表单
+    const onDetail = (record = null, view) => {
+    	indexShow.value = false
+    	nextTick(() => {
+    		if (record) {
+    			detailRef.value.onOpen(record, view)
+    		}
+    	})
+    }
+	const sexOptions = tool.dictList('GENDER')
+</script>

+ 0 - 91
snowy-admin-web/src/views/biz/demo2/detail.vue

@@ -1,91 +0,0 @@
-<template>
-    <a-card :bordered="false">
-		<a-page-header
-            :title="formData.id ? '编辑例子2' : '增加例子2'"
-			@back="onClose"
-		>
-			<template #extra>
-				<a-button style="margin-right: 8px" @click="onClose">关闭</a-button>
-				<a-popconfirm title="请确认是否保存?" @confirm="onSubmit">
-                    <a-button type="primary" :loading="submitLoading">保存</a-button>
-                </a-popconfirm>
-			</template>
-		</a-page-header>
-		<a-form ref="formRef" :model="formData" :rules="formRules" layout="vertical">
-        			<a-row :gutter="16">
-        				<a-col :span="12">
-        					<a-form-item label="NAME:" name="name">
-        						<a-input v-model:value="formData.name" placeholder="请输入NAME" allow-clear />
-        					</a-form-item>
-        				</a-col>
-        				<a-col :span="12">
-        					<a-form-item label="AGE:" name="age">
-        						<a-input v-model:value="formData.age" placeholder="请输入AGE" allow-clear />
-        					</a-form-item>
-        				</a-col>
-        				<a-col :span="12">
-        					<a-form-item label="SEX:" name="sex">
-        						<a-input v-model:value="formData.sex" placeholder="请输入SEX" allow-clear />
-        					</a-form-item>
-        				</a-col>
-        				<a-col :span="12">
-        					<a-form-item label="REMARK:" name="remark">
-        						<a-input v-model:value="formData.remark" placeholder="请输入REMARK" allow-clear />
-        					</a-form-item>
-        				</a-col>
-        			</a-row>
-        		</a-form>
-	</a-card>
-</template>
-
-<script setup name="demo2Detail">
-	import { cloneDeep } from 'lodash-es'
-	import { required } from '@/utils/formRules'
-	import demo2Api from '@/api/biz/demo2Api'
-	// 抽屉状态
-	const emit = defineEmits({ successful: null })
-	const formRef = ref()
-	// 表单数据
-	const formData = ref({})
-	const submitLoading = ref(false)
-
-	// 打开抽屉
-	const onOpen = (record) => {
-		if (record) {
-			let recordData = cloneDeep(record)
-			formData.value = Object.assign({}, recordData)
-		}
-	}
-	// 关闭抽屉
-	const onClose = () => {
-		formRef.value.resetFields()
-		formData.value = {}
-		emit('onClose')
-	}
-	// 默认要校验的
-	const formRules = {
-	}
-	// 验证并提交数据
-	const onSubmit = () => {
-		formRef.value
-			.validate()
-			.then(() => {
-				submitLoading.value = true
-				const formDataParam = cloneDeep(formData.value)
-				demo2Api
-					.demo2SubmitForm(formDataParam, formDataParam.id)
-					.then(() => {
-						onClose()
-						emit('successful')
-					})
-					.finally(() => {
-						submitLoading.value = false
-					})
-			})
-			.catch(() => {})
-	}
-	// 抛出函数
-	defineExpose({
-		onOpen
-	})
-</script>

+ 161 - 0
snowy-admin-web/src/views/biz/demo2/form.vue

@@ -0,0 +1,161 @@
+<template>
+	<xn-form-container
+		:title="formData.id ? '编辑弹窗表单' : '新增弹窗表单'"
+		:width="700"
+		v-model:open="open"
+		:destroy-on-close="true"
+		@close="onClose"
+	>
+		<a-form ref="formRef" :model="formData" :rules="formRules" layout="vertical">
+			<a-row :gutter="16">
+				<a-col :span="12">
+					<a-form-item label="NAME:" name="name">
+						<a-input v-model:value="formData.name" :disabled="isView" placeholder="请输入NAME" allow-clear />
+					</a-form-item>
+				</a-col>
+				<a-col :span="12">
+					<a-form-item label="AGE:" name="age">
+						<a-input v-model:value="formData.age" :disabled="isView" placeholder="请输入AGE" allow-clear />
+					</a-form-item>
+				</a-col>
+				<a-col :span="12">
+					<a-form-item label="SEX:" name="sex">
+						<a-select v-model:value="formData.sex" :disabled="isView" placeholder="请选择SEX" :options="sexOptions" />
+					</a-form-item>
+				</a-col>
+				<a-col :span="12">
+					<a-form-item label="REMARK:" name="remark">
+						<a-input v-model:value="formData.remark" :disabled="isView" placeholder="请输入REMARK" allow-clear />
+					</a-form-item>
+				</a-col>
+				<a-col :span="12">
+					<a-form-item label="P1:" name="p1">
+						<a-input v-model:value="formData.p1" :disabled="isView" placeholder="请输入P1" allow-clear />
+					</a-form-item>
+				</a-col>
+				<a-col :span="12">
+					<a-form-item label="P2:" name="p2">
+						<a-input v-model:value="formData.p2" :disabled="isView" placeholder="请输入P2" allow-clear />
+					</a-form-item>
+				</a-col>
+				<a-col :span="12">
+					<a-form-item label="P3:" name="p3">
+						<a-input v-model:value="formData.p3" :disabled="isView" placeholder="请输入P3" allow-clear />
+					</a-form-item>
+				</a-col>
+				<a-col :span="12">
+					<a-form-item label="P4:" name="p4">
+						<a-input v-model:value="formData.p4" :disabled="isView" placeholder="请输入P4" allow-clear />
+					</a-form-item>
+				</a-col>
+				<a-col :span="12">
+					<a-form-item label="P5:" name="p5">
+						<a-input v-model:value="formData.p5" :disabled="isView" placeholder="请输入P5" allow-clear />
+					</a-form-item>
+				</a-col>
+				<a-col :span="12">
+					<a-form-item label="P6:" name="p6">
+						<a-input v-model:value="formData.p6" :disabled="isView" placeholder="请输入P6" allow-clear />
+					</a-form-item>
+				</a-col>
+				<a-col :span="12">
+					<a-form-item label="P7:" name="p7">
+						<a-input v-model:value="formData.p7" :disabled="isView" placeholder="请输入P7" allow-clear />
+					</a-form-item>
+				</a-col>
+				<a-col :span="12">
+					<a-form-item label="P8:" name="p8">
+						<a-input v-model:value="formData.p8" :disabled="isView" placeholder="请输入P8" allow-clear />
+					</a-form-item>
+				</a-col>
+				<a-col :span="12">
+					<a-form-item label="P9:" name="p9">
+						<a-input v-model:value="formData.p9" :disabled="isView" placeholder="请输入P9" allow-clear />
+					</a-form-item>
+				</a-col>
+				<a-col :span="12">
+					<a-form-item label="P10:" name="p10">
+						<a-input v-model:value="formData.p10" :disabled="isView" placeholder="请输入P10" allow-clear />
+					</a-form-item>
+				</a-col>
+				<a-col :span="12">
+					<a-form-item label="CREATE_BY:" name="createBy">
+						<a-input v-model:value="formData.createBy" :disabled="isView" placeholder="请输入CREATE_BY" allow-clear />
+					</a-form-item>
+				</a-col>
+				<a-col :span="12">
+					<a-form-item label="UPDATE_BY:" name="updateBy">
+						<a-input v-model:value="formData.updateBy" :disabled="isView" placeholder="请输入UPDATE_BY" allow-clear />
+					</a-form-item>
+				</a-col>
+			</a-row>
+		</a-form>
+		<template #footer>
+			<a-button style="margin-right: 8px" @click="onClose">关闭</a-button>
+			<a-popconfirm title="请确认是否保存?" @confirm="onSubmit" v-if="!isView">
+                <a-button type="primary" :loading="submitLoading">保存</a-button>
+            </a-popconfirm>
+		</template>
+	</xn-form-container>
+</template>
+
+<script setup name="demo2Form">
+	import tool from '@/utils/tool'
+	import { cloneDeep } from 'lodash-es'
+	import { required } from '@/utils/formRules'
+	import demo2Api from '@/api/biz/demo2Api'
+	// 抽屉状态
+	const open = ref(false)
+	const emit = defineEmits({ successful: null })
+	const formRef = ref()
+	// 表单数据
+	const formData = ref({})
+	const submitLoading = ref(false)
+	const isView = ref(false)
+	const sexOptions = ref([])
+
+	// 打开抽屉
+	const onOpen = (record, view = false) => {
+		open.value = true
+		isView.value = view
+		if (record) {
+			let recordData = cloneDeep(record)
+			formData.value = Object.assign({}, recordData)
+		}
+		sexOptions.value = tool.dictList('GENDER')
+	}
+	// 关闭抽屉
+	const onClose = () => {
+		formRef.value.resetFields()
+		formData.value = {}
+		open.value = false
+		isView.value = true
+	}
+	// 默认要校验的
+	const formRules = {
+		name: [required('请输入NAME')],
+	}
+	// 验证并提交数据
+	const onSubmit = () => {
+		formRef.value
+			.validate()
+			.then(() => {
+				submitLoading.value = true
+				const formDataParam = cloneDeep(formData.value)
+				demo2Api
+					.demo2SubmitForm(formDataParam, formDataParam.id)
+					.then(() => {
+						onClose()
+						emit('successful')
+					})
+					.finally(() => {
+						submitLoading.value = false
+					})
+			})
+			.catch(() => {})
+	}
+	// 抛出函数
+	defineExpose({
+		onOpen
+	})
+</script>

+ 112 - 49
snowy-admin-web/src/views/biz/demo2/index.vue

@@ -1,5 +1,5 @@
 <template>
-	<a-card :bordered="false" v-if="indexShow">
+	<a-card :bordered="false">
 		<a-form ref="searchFormRef" name="advanced_search" :model="searchFormState" class="ant-advanced-search-form">
 			<a-row :gutter="24">
 				<a-col :span="6">
@@ -8,27 +8,8 @@
 					</a-form-item>
 				</a-col>
 				<a-col :span="6">
-					<a-form-item label="AGE" name="age">
-						<a-input v-model:value="searchFormState.age" placeholder="请输入AGE" />
-					</a-form-item>
-				</a-col>
-				<a-col :span="6">
-					<a-form-item label="SEX" name="sex">
-						<a-input v-model:value="searchFormState.sex" placeholder="请输入SEX" />
-					</a-form-item>
-				</a-col>
-				<a-col :span="6" v-show="advanced">
-					<a-form-item label="REMARK" name="remark">
-						<a-input v-model:value="searchFormState.remark" placeholder="请输入REMARK" />
-					</a-form-item>
-				</a-col>
-				<a-col :span="6">
-					<a-button type="primary" @click="tableRef.refresh()">查询</a-button>
+					<a-button type="primary" @click="onSearch()">查询</a-button>
 					<a-button style="margin: 0 8px" @click="reset">重置</a-button>
-					<a @click="toggleAdvanced" style="margin-left: 8px">
-						{{ advanced ? '收起' : '展开' }}
-						<component :is="advanced ? 'up-outlined' : 'down-outlined'"/>
-					</a>
 				</a-col>
 			</a-row>
 		</a-form>
@@ -41,24 +22,35 @@
 			:row-key="(record) => record.id"
 			:tool-config="toolConfig"
 			:row-selection="options.rowSelection"
+			v-model:filterParam="filterParam"
+			:scroll="{ x: 2000 }"
 		>
 			<template #operator class="table-operator">
 				<a-space>
-					<a-button type="primary" @click="onDetail()" v-if="hasPerm('demo2Add')">
+					<a-button type="primary" @click="formRef.onOpen()" v-if="hasPerm('demo2Add')">
 						<template #icon><plus-outlined /></template>
 						新增
 					</a-button>
 					<xn-batch-delete
-						v-if="hasPerm('demo2BatchDelete')"
+						v-if="hasPerm('demo2Delete')"
 						:selectedRowKeys="selectedRowKeys"
 						@batchDelete="deleteBatchDemo2"
 					/>
+					<a-button @click="onExport" v-if="hasPerm('demo2BatchExport')">
+                        <template #icon><export-outlined /></template>
+                        批量导出
+                    </a-button>
 				</a-space>
 			</template>
 			<template #bodyCell="{ column, record }">
+				<template v-if="column.dataIndex === 'sex'">
+					{{ $TOOL.dictTypeData('GENDER', record.sex) }}
+				</template>
 				<template v-if="column.dataIndex === 'action'">
 					<a-space>
-						<a @click="onDetail(record)" v-if="hasPerm('demo2Edit')">编辑</a>
+						<a @click="formRef.onOpen(record)" v-if="hasPerm('demo2View')">查看</a>
+						<a-divider type="vertical" v-if="hasPerm('demo2View') && hasPerm(['demo2Edit', 'demo2Delete'], 'or')" />
+						<a @click="formRef.onOpen(record)" v-if="hasPerm('demo2Edit')">编辑</a>
 						<a-divider type="vertical" v-if="hasPerm(['demo2Edit', 'demo2Delete'], 'and')" />
 						<a-popconfirm title="确定要删除吗?" @confirm="deleteDemo2(record)">
 							<a-button type="link" danger size="small" v-if="hasPerm('demo2Delete')">删除</a-button>
@@ -68,40 +60,95 @@
 			</template>
 		</s-table>
 	</a-card>
-	<Detail v-else ref="detailRef" @onClose="indexShow = true" @successful="tableRef.refresh()" />
+	<Form ref="formRef" @successful="onSearch()" />
 </template>
 
 <script setup name="demo2">
+	import tool from '@/utils/tool'
 	import { cloneDeep } from 'lodash-es'
-	import Detail from './detail.vue'
+	import Form from './form.vue'
 	import demo2Api from '@/api/biz/demo2Api'
+	import downloadUtil from "@/utils/downloadUtil";
+    const { proxy } = getCurrentInstance()
 	const searchFormState = ref({})
+	const searchFormStateReal = ref({}) // 点击搜索后备份的查询参数
 	const searchFormRef = ref()
 	const tableRef = ref()
-	const detailRef = ref()
-	const indexShow = ref(true)
+	const filterParam = ref({})
+	const formRef = ref()
 	const toolConfig = { refresh: true, height: true, columnSetting: true, striped: false }
-	// 查询区域显示更多控制
-	const advanced = ref(false)
-	const toggleAdvanced = () => {
-		advanced.value = !advanced.value
-	}
 	const columns = [
 		{
 			title: 'NAME',
-			dataIndex: 'name'
+			dataIndex: 'name',
 		},
 		{
 			title: 'AGE',
-			dataIndex: 'age'
+			dataIndex: 'age',
 		},
 		{
 			title: 'SEX',
-			dataIndex: 'sex'
+			dataIndex: 'sex',
 		},
 		{
 			title: 'REMARK',
-			dataIndex: 'remark'
+			dataIndex: 'remark',
+		},
+		{
+			title: 'P1',
+			dataIndex: 'p1',
+		},
+		{
+			title: 'P2',
+			dataIndex: 'p2',
+		},
+		{
+			title: 'P3',
+			dataIndex: 'p3',
+		},
+		{
+			title: 'P4',
+			dataIndex: 'p4',
+		},
+		{
+			title: 'P5',
+			dataIndex: 'p5',
+		},
+		{
+			title: 'P6',
+			dataIndex: 'p6',
+		},
+		{
+			title: 'P7',
+			dataIndex: 'p7',
+		},
+		{
+			title: 'P8',
+			dataIndex: 'p8',
+		},
+		{
+			title: 'P9',
+			dataIndex: 'p9',
+		},
+		{
+			title: 'P10',
+			dataIndex: 'p10',
+		},
+		{
+			title: 'CREATE_TIME',
+			dataIndex: 'createTime',
+		},
+		{
+			title: 'CREATE_BY',
+			dataIndex: 'createBy',
+		},
+		{
+			title: 'UPDATE_TIME',
+			dataIndex: 'updateTime',
+		},
+		{
+			title: 'UPDATE_BY',
+			dataIndex: 'updateBy',
 		},
 	]
 	// 操作栏通过权限判断是否显示
@@ -110,7 +157,8 @@
 			title: '操作',
 			dataIndex: 'action',
 			align: 'center',
-			width: 150
+			width: 200,
+			fixed: 'right',
 		})
 	}
 	const selectedRowKeys = ref([])
@@ -130,15 +178,19 @@
 		}
 	}
 	const loadData = (parameter) => {
-		const searchFormParam = cloneDeep(searchFormState.value)
-		return demo2Api.demo2Page(Object.assign(parameter, searchFormParam)).then((data) => {
+		return demo2Api.demo2Page(Object.assign(parameter, searchFormStateReal.value)).then((data) => {
 			return data
 		})
 	}
+	// 搜索同时备份参数
+    const onSearch = (parameter) => {
+        searchFormStateReal.value = cloneDeep(searchFormState.value)
+        tableRef.value.refresh(parameter)
+    }
 	// 重置
 	const reset = () => {
 		searchFormRef.value.resetFields()
-		tableRef.value.refresh(true)
+		onSearch(true)
 	}
 	// 删除
 	const deleteDemo2 = (record) => {
@@ -157,13 +209,24 @@
 			tableRef.value.clearRefreshSelected()
 		})
 	}
-	// 切换至表单
-    const onDetail = (record = null) => {
-    	indexShow.value = false
-    	nextTick(() => {
-    		if (record) {
-    			detailRef.value.onOpen(record)
-    		}
-    	})
+	// 批量导出
+    const onExport = () => {
+        const params = {
+            ...filterParam.value
+        }
+        if (selectedRowKeys.value.length > 0) {
+            params.ids = selectedRowKeys.value
+        } else {
+            Object.entries(searchFormStateReal.value).forEach(([key, value]) => {
+                console.log(key)
+                if (proxy.$util.isValue(value)) {
+                    params[key] = value
+                }
+            })
+        }
+        demo2Api.demo2Export(params).then((res) => {
+            downloadUtil.resultDownload(res)
+            tableRef.value.clearSelected()
+        })
     }
 </script>

+ 409 - 376
snowy-admin-web/src/views/gen/config.vue

@@ -8,9 +8,9 @@
 			:showPagination="false"
 			bordered
 		>
-			<template #bodyCell="{ column, record }">
+			<template #bodyCell="{ column, record, index }">
 				<template v-if="column.dataIndex === 'fieldRemark'">
-					<a-input v-model:value="record.fieldRemark" />
+					<a-input v-model:value="record.fieldRemark"/>
 				</template>
 				<template v-if="column.dataIndex === 'fieldJavaType'">
 					<a-select
@@ -46,20 +46,20 @@
 					<a-checkbox v-model:checked="record.whetherTable" @change="whetherTableChange(record)"/>
 				</template>
 				<template v-if="column.dataIndex === 'whetherRetract'">
-					<a-checkbox v-model:checked="record.whetherRetract" :disabled="!record.whetherTable" />
+					<a-checkbox v-model:checked="record.whetherRetract" :disabled="!record.whetherTable"/>
 				</template>
 				<template v-if="column.dataIndex === 'whetherSort'">
-					<a-checkbox v-model:checked="record.whetherSort" :disabled="!record.whetherTable" />
+					<a-checkbox v-model:checked="record.whetherSort" :disabled="!record.whetherTable"/>
 				</template>
 				<template v-if="column.dataIndex === 'whetherFixed'">
-				  <a-radio-group v-model:value="record.whetherFixed" button-style="solid" size="small">
-            <a-radio-button :value="1">左</a-radio-button>
-            <a-radio-button :value="0">默认</a-radio-button>
-            <a-radio-button :value="2">右</a-radio-button>
-				  </a-radio-group>
+					<a-radio-group v-model:value="record.whetherFixed" button-style="solid" size="small">
+						<a-radio-button :value="1">左</a-radio-button>
+						<a-radio-button :value="0">默认</a-radio-button>
+						<a-radio-button :value="2">右</a-radio-button>
+					</a-radio-group>
 				</template>
 				<template v-if="column.dataIndex === 'whetherAddUpdate'">
-					<a-checkbox v-model:checked="record.whetherAddUpdate" :disabled="toFieldEstimate(record)" />
+					<a-checkbox v-model:checked="record.whetherAddUpdate" :disabled="toFieldEstimate(record)"/>
 				</template>
 				<template v-if="column.dataIndex === 'whetherRequired'">
 					<a-checkbox
@@ -68,7 +68,7 @@
 					/>
 				</template>
 				<template v-if="column.dataIndex === 'queryWhether'">
-					<a-switch v-model:checked="record.queryWhether" :disabled="toQueryWhetherDisabled(record)" />
+					<a-switch v-model:checked="record.queryWhether" :disabled="toQueryWhetherDisabled(record)"/>
 				</template>
 				<template v-if="column.dataIndex === 'queryType'">
 					<a-select
@@ -81,399 +81,432 @@
 					<span v-else-if="record.effectType === 'datepicker' && record.queryWhether === true">时间段</span>
 					<span v-else>无</span>
 				</template>
+				<template v-if="column.dataIndex === 'move'">
+					<a-button type="primary" shape="circle" v-if="index !== 0" @click="rowMove(true, index)"
+							  :style="{marginRight: index > 0 ? '10px' : 0}">
+						<template #icon>
+							<ArrowUpOutlined/>
+						</template>
+					</a-button>
+					<a-button type="primary" shape="circle" v-if="index < tableData.length - 1"
+							  @click="rowMove(false, index)">
+						<template #icon>
+							<ArrowDownOutlined/>
+						</template>
+					</a-button>
+				</template>
 			</template>
 		</s-table>
 	</a-card>
 </template>
 
 <script setup name="genConfig">
-	import tool from '@/utils/tool'
-	import genConfigApi from '@/api/gen/genConfigApi'
-	import { cloneDeep } from 'lodash-es'
+import tool from '@/utils/tool'
+import genConfigApi from '@/api/gen/genConfigApi'
+import {cloneDeep} from 'lodash-es'
 
-	const tableRef = ref()
-	const recordData = ref()
-	const tableData = ref()
+const tableRef = ref()
+const recordData = ref()
+const tableData = ref()
 
-	const columns = [
-		{
-			title: '字段',
-			align: 'center',
-			dataIndex: 'fieldName',
-			ellipsis: true
-		},
-		{
-			title: '注释',
-			align: 'center',
-			dataIndex: 'fieldRemark',
-			ellipsis: true
-		},
-		{
-			title: '类型',
-			align: 'center',
-			dataIndex: 'fieldType',
-			ellipsis: true
-		},
-		{
-			title: '实体类型',
-			align: 'center',
-			dataIndex: 'fieldJavaType',
-			ellipsis: true
-		},
-		{
-			title: '作用类型',
-			align: 'center',
-			dataIndex: 'effectType',
-			ellipsis: true
-		},
-		{
-			title: '字典',
-			align: 'center',
-			dataIndex: 'dictTypeCode',
-			width: 140
-		},
-		{
-			title: '列表显示',
-			align: 'center',
-			dataIndex: 'whetherTable',
-			width: 80
-		},
-		{
-			title: '列省略',
-			align: 'center',
-			dataIndex: 'whetherRetract',
-			width: 80
-		},
-		{
-			title: '列排序',
-			align: 'center',
-			dataIndex: 'whetherSort',
-			width: 80
-		},
-		{
-			title: '列固定',
-			align: 'center',
-			dataIndex: 'whetherFixed',
-			width: 140
-		},
-		{
-			title: '增改',
-			align: 'center',
-			dataIndex: 'whetherAddUpdate',
-			width: 80
-		},
-		{
-			title: '必填',
-			align: 'center',
-			dataIndex: 'whetherRequired',
-			width: 80
-		},
-		{
-			title: '查询',
-			align: 'center',
-			dataIndex: 'queryWhether',
-			width: 80
-		},
-		{
-			title: '查询方式',
-			align: 'center',
-			dataIndex: 'queryType'
-		}
-	]
-	const onOpen = (record) => {
-		recordData.value = record
-		nextTick(() => {
-			tableRef.value.refresh()
-		})
+const columns = [
+	{
+		title: '字段',
+		align: 'center',
+		dataIndex: 'fieldName',
+		ellipsis: true
+	},
+	{
+		title: '注释',
+		align: 'center',
+		dataIndex: 'fieldRemark',
+		ellipsis: true
+	},
+	{
+		title: '类型',
+		align: 'center',
+		dataIndex: 'fieldType',
+		ellipsis: true
+	},
+	{
+		title: '实体类型',
+		align: 'center',
+		dataIndex: 'fieldJavaType',
+		ellipsis: true
+	},
+	{
+		title: '作用类型',
+		align: 'center',
+		dataIndex: 'effectType',
+		ellipsis: true
+	},
+	{
+		title: '字典',
+		align: 'center',
+		dataIndex: 'dictTypeCode',
+		width: 140
+	},
+	{
+		title: '列表显示',
+		align: 'center',
+		dataIndex: 'whetherTable',
+		width: 80
+	},
+	{
+		title: '列省略',
+		align: 'center',
+		dataIndex: 'whetherRetract',
+		width: 80
+	},
+	{
+		title: '列排序',
+		align: 'center',
+		dataIndex: 'whetherSort',
+		width: 80
+	},
+	{
+		title: '列固定',
+		align: 'center',
+		dataIndex: 'whetherFixed',
+		width: 140
+	},
+	{
+		title: '增改',
+		align: 'center',
+		dataIndex: 'whetherAddUpdate',
+		width: 80
+	},
+	{
+		title: '必填',
+		align: 'center',
+		dataIndex: 'whetherRequired',
+		width: 80
+	},
+	{
+		title: '查询',
+		align: 'center',
+		dataIndex: 'queryWhether',
+		width: 80
+	},
+	{
+		title: '查询方式',
+		align: 'center',
+		dataIndex: 'queryType'
+	},
+	{
+		title: '移动',
+		align: 'center',
+		dataIndex: 'move',
+		width: 120
 	}
-	// 表格查询 返回 Promise 对象
-	const loadDate = (parameter) => {
-		if (recordData.value) {
-			parameter.basicId = recordData.value.id
-			return genConfigApi.configList(parameter).then((data) => {
-				tableData.value = JSON.parse(JSON.stringify(data))
-				let deleteIndex = []
-				tableData.value.forEach((item, index) => {
-					for (const key in item) {
-						if (item[key] === 'Y') {
-							item[key] = true
-						}
-						if (item[key] === 'N') {
-							item[key] = false
-						}
-					}
-					// 如果是主键,我们不提供主键的配置,也用不到
-					if (item.isTableKey) {
-						deleteIndex.push(index)
+]
+const onOpen = (record) => {
+	recordData.value = record
+	nextTick(() => {
+		tableRef.value.refresh()
+	})
+}
+// 表格查询 返回 Promise 对象
+const loadDate = (parameter) => {
+	if (recordData.value) {
+		parameter.basicId = recordData.value.id
+		return genConfigApi.configList(parameter).then((data) => {
+			tableData.value = JSON.parse(JSON.stringify(data))
+			let deleteIndex = []
+			tableData.value.forEach((item, index) => {
+				for (const key in item) {
+					if (item[key] === 'Y') {
+						item[key] = true
 					}
-					// 去掉删除标识
-					if (item.fieldName.toLowerCase().indexOf('delete_flag') > -1) {
-						deleteIndex.push(index)
+					if (item[key] === 'N') {
+						item[key] = false
 					}
-					// 让默认的变成设置的
-					fieldJavaTypeChange(item)
-				})
-				if (deleteIndex) {
-					deleteIndex.forEach((item, index) => {
-						if (index > 0) {
-							item = item - 1
-						}
-						delete tableData.value.splice(item, 1)
-					})
 				}
-				return tableData.value
-			})
-		} else {
-			return new Promise((resolve, reject) => {
-				resolve([])
+				// 如果是主键,我们不提供主键的配置,也用不到
+				if (item.isTableKey) {
+					deleteIndex.push(index)
+				}
+				// 去掉删除标识
+				if (item.fieldName.toLowerCase().indexOf('delete_flag') > -1) {
+					deleteIndex.push(index)
+				}
+				// 让默认的变成设置的
+				fieldJavaTypeChange(item)
 			})
-		}
+			if (deleteIndex) {
+				deleteIndex.forEach((item, index) => {
+					if (index > 0) {
+						item = item - 1
+					}
+					delete tableData.value.splice(item, 1)
+				})
+			}
+			return tableData.value
+		})
+	} else {
+		return new Promise((resolve, reject) => {
+			resolve([])
+		})
 	}
-	// 实体类型
-	const fieldJavaTypeOptions = ref([
-		{
-			label: 'Integer',
-			value: 'Integer'
-		},
-		{
-			label: 'Long',
-			value: 'Long'
-		},
-		{
-			label: 'String',
-			value: 'String'
-		},
-		{
-			label: 'Boolean',
-			value: 'Boolean'
-		},
-		{
-			label: 'Float',
-			value: 'Float'
-		},
-		{
-			label: 'Double',
-			value: 'Double'
-		},
-		{
-			label: 'Date',
-			value: 'Date'
-		},
-		{
-			label: 'BigDecimal',
-			value: 'BigDecimal'
-		}
-	])
-	// 类型
-	const effectTypeOptions = ref([
-		{
-			label: '输入框',
-			value: 'input'
-		},
-		{
-			label: '文本框',
-			value: 'textarea'
-		},
-		{
-			label: '下拉框',
-			value: 'select'
-		},
-		{
-			label: '单选框',
-			value: 'radio'
-		},
-		{
-			label: '复选框',
-			value: 'checkbox'
-		},
-		{
-			label: '日期选择器',
-			value: 'datepicker'
-		},
-		{
-			label: '时间选择器',
-			value: 'timepicker'
-		},
-		{
-			label: '数字输入框',
-			value: 'inputNumber'
-		},
-		{
-			label: '滑动数字条',
-			value: 'slider'
-		},
-		{
-			label: '图片上传',
-			value: 'imageUpload'
-		},
-		{
-			label: '文件上传',
-			value: 'fileUpload'
-		},
-		{
-			label: '富文本',
-			value: 'editor'
-		}
-	])
-	// 字典数据
-	const dictTypeCodeOptions = tool.dictDataAll().map((item) => {
-		return {
-			label: item.name,
-			value: item.dictValue
-		}
-	})
-	// 查询方式
-	const queryTypeOptions = ref([
-		{
-			label: '模糊包含',
-			value: 'like'
-		},
-		{
-			label: '模糊不包含',
-			value: 'notLike'
-		},
-		{
-			label: '等于',
-			value: 'eq'
-		},
-		{
-			label: '不等于',
-			value: 'ne'
-		},
-		{
-			label: '大于',
-			value: 'gt'
-		},
-		{
-			label: '大于等于',
-			value: 'ge'
-		},
-		{
-			label: '小于',
-			value: 'lt'
-		},
-		{
-			label: '小于等于',
-			value: 'le'
-		}
-	])
-	const emit = defineEmits({ successful: null }, { close: null })
-	const toFieldEstimate = (data) => {
-		if (
-			data.fieldName.toLowerCase().indexOf('create_user') > -1 ||
-			data.fieldName.toLowerCase().indexOf('create_time') > -1 ||
-			data.fieldName.toLowerCase().indexOf('update_user') > -1 ||
-			data.fieldName.toLowerCase().indexOf('update_time') > -1 ||
-			data.fieldName.toLowerCase().indexOf('delete_flag') > -1 ||
-			data.isTableKey === true
-		) {
-			return true
-		}
-		return false
+}
+// 实体类型
+const fieldJavaTypeOptions = ref([
+	{
+		label: 'Integer',
+		value: 'Integer'
+	},
+	{
+		label: 'Long',
+		value: 'Long'
+	},
+	{
+		label: 'String',
+		value: 'String'
+	},
+	{
+		label: 'Boolean',
+		value: 'Boolean'
+	},
+	{
+		label: 'Float',
+		value: 'Float'
+	},
+	{
+		label: 'Double',
+		value: 'Double'
+	},
+	{
+		label: 'Date',
+		value: 'Date'
+	},
+	{
+		label: 'BigDecimal',
+		value: 'BigDecimal'
 	}
-	// 通用字段是否可选
-	const toCommonFieldEstimate = (record) => {
-		if (
-			record.fieldName.toLowerCase().indexOf('create_user') > -1 ||
-			record.fieldName.toLowerCase().indexOf('update_user') > -1
-		) {
-			return true
-		}
-		return false
+])
+// 类型
+const effectTypeOptions = ref([
+	{
+		label: '输入框',
+		value: 'input'
+	},
+	{
+		label: '文本框',
+		value: 'textarea'
+	},
+	{
+		label: '下拉框',
+		value: 'select'
+	},
+	{
+		label: '单选框',
+		value: 'radio'
+	},
+	{
+		label: '复选框',
+		value: 'checkbox'
+	},
+	{
+		label: '日期选择器',
+		value: 'datepicker'
+	},
+	{
+		label: '时间选择器',
+		value: 'timepicker'
+	},
+	{
+		label: '数字输入框',
+		value: 'inputNumber'
+	},
+	{
+		label: '滑动数字条',
+		value: 'slider'
+	},
+	{
+		label: '图片上传',
+		value: 'imageUpload'
+	},
+	{
+		label: '文件上传',
+		value: 'fileUpload'
+	},
+	{
+		label: '富文本',
+		value: 'editor'
 	}
-	// 设置该下拉框是否能选
-	const toFieldSelectEstimate = (record) => {
-		if (record.fieldJavaType === 'Date' && record.effectType === 'datepicker') {
-			return true
-		}
-		return false
+])
+// 字典数据
+const dictTypeCodeOptions = tool.dictDataAll().map((item) => {
+	return {
+		label: item.name,
+		value: item.dictValue
 	}
-	// 选择作用类型触发-这里只负责字段类型的赋值,至于禁用是每一个字段自己的
-	const effectTypeChange = (record) => {
-		// 图片跟文件不可设置查询跟查询方式
-		if (record.effectType === 'imageUpload' || record.effectType === 'fileUpload') {
-			record.queryWhether = 'N'
-			record.queryType = null
-		}
-		// 富文本只能模糊包含跟模糊不包含
-		if (record.effectType === 'editor') {
-			record.whetherTable = false
-			record.whetherRetract = false
-			record.whetherSort = false
-			record.whetherFixed = 0
-			record.queryWhether = 'N'
-			record.queryType = null
-		}
+})
+// 查询方式
+const queryTypeOptions = ref([
+	{
+		label: '模糊包含',
+		value: 'like'
+	},
+	{
+		label: '模糊不包含',
+		value: 'notLike'
+	},
+	{
+		label: '等于',
+		value: 'eq'
+	},
+	{
+		label: '不等于',
+		value: 'ne'
+	},
+	{
+		label: '大于',
+		value: 'gt'
+	},
+	{
+		label: '大于等于',
+		value: 'ge'
+	},
+	{
+		label: '小于',
+		value: 'lt'
+	},
+	{
+		label: '小于等于',
+		value: 'le'
 	}
-	// 点击列表显示,处理
-	const whetherTableChange = (record) => {
-		// 如果去除了勾选,清理部分数据
-		if (!record.whetherTable) {
-			record.queryWhether = 'N'
-			record.queryType = null
-		}
+])
+const emit = defineEmits({successful: null}, {close: null})
+const toFieldEstimate = (data) => {
+	if (
+		data.fieldName.toLowerCase().indexOf('create_user') > -1 ||
+		data.fieldName.toLowerCase().indexOf('create_time') > -1 ||
+		data.fieldName.toLowerCase().indexOf('update_user') > -1 ||
+		data.fieldName.toLowerCase().indexOf('update_time') > -1 ||
+		data.fieldName.toLowerCase().indexOf('delete_flag') > -1 ||
+		data.isTableKey === true
+	) {
+		return true
 	}
-	// 查询条件是否可用
-	const toQueryWhetherDisabled = (record) => {
-		// 去掉了列表显示、图片上传、文件上传是不让生成搜索的
-		return !record.whetherTable || record.effectType === 'imageUpload' || record.effectType === 'fileUpload'
+	return false
+}
+// 通用字段是否可选
+const toCommonFieldEstimate = (record) => {
+	if (
+		record.fieldName.toLowerCase().indexOf('create_user') > -1 ||
+		record.fieldName.toLowerCase().indexOf('update_user') > -1
+	) {
+		return true
 	}
-	// 实体类型选择触发
-	const fieldJavaTypeChange = (record) => {
-		if (record.fieldJavaType === 'Date') {
-			record.effectType = 'datepicker'
-		}
+	return false
+}
+// 设置该下拉框是否能选
+const toFieldSelectEstimate = (record) => {
+	if (record.fieldJavaType === 'Date' && record.effectType === 'datepicker') {
+		return true
 	}
-	// 提交
-	const onSubmit = (recordData) => {
-		let submitParam = cloneDeep(tableData.value)
-		let errStatus = 100
-		submitParam.forEach((item) => {
-			// 必填那一项转换
-			for (const key in item) {
-				if (item[key] === true) {
-					item[key] = 'Y'
-				}
-				if (item[key] === false) {
-					item[key] = 'N'
-				}
+	return false
+}
+// 选择作用类型触发-这里只负责字段类型的赋值,至于禁用是每一个字段自己的
+const effectTypeChange = (record) => {
+	// 图片跟文件不可设置查询跟查询方式
+	if (record.effectType === 'imageUpload' || record.effectType === 'fileUpload') {
+		record.queryWhether = 'N'
+		record.queryType = null
+	}
+	// 富文本只能模糊包含跟模糊不包含
+	if (record.effectType === 'editor') {
+		record.whetherTable = false
+		record.whetherRetract = false
+		record.whetherSort = false
+		record.whetherFixed = 0
+		record.queryWhether = 'N'
+		record.queryType = null
+	}
+}
+// 点击列表显示,处理
+const whetherTableChange = (record) => {
+	// 如果去除了勾选,清理部分数据
+	if (!record.whetherTable) {
+		record.queryWhether = 'N'
+		record.queryType = null
+	}
+}
+// 查询条件是否可用
+const toQueryWhetherDisabled = (record) => {
+	// 去掉了列表显示、图片上传、文件上传是不让生成搜索的
+	return !record.whetherTable || record.effectType === 'imageUpload' || record.effectType === 'fileUpload'
+}
+// 实体类型选择触发
+const fieldJavaTypeChange = (record) => {
+	if (record.fieldJavaType === 'Date') {
+		record.effectType = 'datepicker'
+	}
+}
+// 提交
+const onSubmit = (recordData) => {
+	let submitParam = cloneDeep(tableData.value)
+	let errStatus = 100
+	submitParam.forEach((item, index) => {
+		// 必填那一项转换
+		for (const key in item) {
+			if (item[key] === true) {
+				item[key] = 'Y'
 			}
-			if (item.queryWhether === 'Y' && !item.queryType) {
-				// 排除掉时间选择
-				if (item.fieldJavaType !== 'Date' && item.effectType !== 'checkbox') {
-					errStatus++
-				}
+			if (item[key] === false) {
+				item[key] = 'N'
 			}
-			if (
-				(item.effectType === 'select' || item.effectType === 'radio' || item.effectType === 'checkbox') &&
-				!item.dictTypeCode
-			) {
+		}
+		if (item.queryWhether === 'Y' && !item.queryType) {
+			// 排除掉时间选择
+			if (item.fieldJavaType !== 'Date' && item.effectType !== 'checkbox') {
 				errStatus++
 			}
+		}
+		if (
+			(item.effectType === 'select' || item.effectType === 'radio' || item.effectType === 'checkbox') &&
+			!item.dictTypeCode
+		) {
+			errStatus++
+		}
+		// 排序码重新生成,+1补位ID
+		item.sortCode = index + 1
+	})
+	return new Promise((resolve, reject) => {
+		if (errStatus > 100) {
+			reject('校验失败,请选择对应的下拉框选项')
+			return
+		}
+		genConfigApi
+		.configEditBatch(submitParam)
+		.then((data) => {
+			resolve(data)
 		})
-		return new Promise((resolve, reject) => {
-			if (errStatus > 100) {
-				reject('校验失败,请选择对应的下拉框选项')
-				return
-			}
-			genConfigApi
-				.configEditBatch(submitParam)
-				.then((data) => {
-					resolve(data)
-				})
-				.catch((err) => {
-					reject(err)
-				})
+		.catch((err) => {
+			reject(err)
 		})
-	}
-	// 抛出钩子
-	defineExpose({
-		onOpen,
-		onSubmit
 	})
+}
+const rowMove = (flag, index) => {
+	if (flag) {
+		let temp = tableData.value[index - 1]
+		tableData.value[index - 1] = tableData.value[index]
+		tableData.value[index] = temp
+	} else {
+		let temp = tableData.value[index + 1]
+		tableData.value[index + 1] = tableData.value[index]
+		tableData.value[index] = temp
+	}
+}
+// 抛出钩子
+defineExpose({
+	onOpen,
+	onSubmit
+})
 </script>
 <style scoped>
-	.table-wrapper {
-		margin-top: -16px !important;
-	}
+.table-wrapper {
+	margin-top: -16px !important;
+}
 </style>

+ 0 - 123
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo/controller/DemoController.java

@@ -1,123 +0,0 @@
-/*
- * Copyright [2022] [https://www.xiaonuo.vip]
- *
- * Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
- *
- * 1.请不要删除和修改根目录下的LICENSE文件。
- * 2.请不要删除和修改Snowy源码头部的版权声明。
- * 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
- * 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
- * 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
- * 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
- */
-package vip.xiaonuo.biz.modular.demo.controller;
-
-import cn.dev33.satoken.annotation.SaCheckPermission;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import io.swagger.v3.oas.annotations.Operation;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RestController;
-import vip.xiaonuo.common.annotation.CommonLog;
-import vip.xiaonuo.common.pojo.CommonResult;
-import vip.xiaonuo.biz.modular.demo.entity.Demo;
-import vip.xiaonuo.biz.modular.demo.param.DemoAddParam;
-import vip.xiaonuo.biz.modular.demo.param.DemoEditParam;
-import vip.xiaonuo.biz.modular.demo.param.DemoIdParam;
-import vip.xiaonuo.biz.modular.demo.param.DemoPageParam;
-import vip.xiaonuo.biz.modular.demo.service.DemoService;
-
-import jakarta.annotation.Resource;
-import jakarta.validation.Valid;
-import jakarta.validation.constraints.NotEmpty;
-import java.util.List;
-
-/**
- * 例子控制器
- *
- * @author 曹钊瑞
- * @date  2024/07/01 17:46
- */
-@Tag(name = "例子控制器")
-@RestController
-@Validated
-public class DemoController {
-
-    @Resource
-    private DemoService demoService;
-
-    /**
-     * 获取例子分页
-     *
-     * @author 曹钊瑞
-     * @date  2024/07/01 17:46
-     */
-    @Operation(summary = "获取例子分页")
-    @SaCheckPermission("/biz/demo/page")
-    @GetMapping("/biz/demo/page")
-    public CommonResult<Page<Demo>> page(DemoPageParam demoPageParam) {
-        return CommonResult.data(demoService.page(demoPageParam));
-    }
-
-    /**
-     * 添加例子
-     *
-     * @author 曹钊瑞
-     * @date  2024/07/01 17:46
-     */
-    @Operation(summary = "添加例子")
-    @CommonLog("添加例子")
-    @SaCheckPermission("/biz/demo/add")
-    @PostMapping("/biz/demo/add")
-    public CommonResult<String> add(@RequestBody @Valid DemoAddParam demoAddParam) {
-        demoService.add(demoAddParam);
-        return CommonResult.ok();
-    }
-
-    /**
-     * 编辑例子
-     *
-     * @author 曹钊瑞
-     * @date  2024/07/01 17:46
-     */
-    @Operation(summary = "编辑例子")
-    @CommonLog("编辑例子")
-    @SaCheckPermission("/biz/demo/edit")
-    @PostMapping("/biz/demo/edit")
-    public CommonResult<String> edit(@RequestBody @Valid DemoEditParam demoEditParam) {
-        demoService.edit(demoEditParam);
-        return CommonResult.ok();
-    }
-
-    /**
-     * 删除例子
-     *
-     * @author 曹钊瑞
-     * @date  2024/07/01 17:46
-     */
-    @Operation(summary = "删除例子")
-    @CommonLog("删除例子")
-    @SaCheckPermission("/biz/demo/delete")
-    @PostMapping("/biz/demo/delete")
-    public CommonResult<String> delete(@RequestBody @Valid @NotEmpty(message = "集合不能为空")
-                                                   List<DemoIdParam> demoIdParamList) {
-        demoService.delete(demoIdParamList);
-        return CommonResult.ok();
-    }
-
-    /**
-     * 获取例子详情
-     *
-     * @author 曹钊瑞
-     * @date  2024/07/01 17:46
-     */
-    @Operation(summary = "获取例子详情")
-    @SaCheckPermission("/biz/demo/detail")
-    @GetMapping("/biz/demo/detail")
-    public CommonResult<Demo> detail(@Valid DemoIdParam demoIdParam) {
-        return CommonResult.data(demoService.detail(demoIdParam));
-    }
-}

+ 0 - 59
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo/entity/Demo.java

@@ -1,59 +0,0 @@
-/*
- * Copyright [2022] [https://www.xiaonuo.vip]
- *
- * Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
- *
- * 1.请不要删除和修改根目录下的LICENSE文件。
- * 2.请不要删除和修改Snowy源码头部的版权声明。
- * 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
- * 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
- * 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
- * 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
- */
-package vip.xiaonuo.biz.modular.demo.entity;
-
-import com.baomidou.mybatisplus.annotation.*;
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Getter;
-import lombok.Setter;
-import java.math.BigDecimal;
-import java.util.Date;
-
-/**
- * 例子实体
- *
- * @author 曹钊瑞
- * @date  2024/07/01 17:46
- **/
-@Getter
-@Setter
-@TableName("demo")
-public class Demo {
-
-    /** ID */
-    @TableId
-    @Schema(description = "ID")
-    private String id;
-
-    /** NAME */
-    @Schema(description = "NAME")
-    private String name;
-
-    /** AGE */
-    @Schema(description = "AGE")
-    private String age;
-
-    /** SEX */
-    @Schema(description = "SEX")
-    private String sex;
-
-    /** REMARK */
-    @Schema(description = "REMARK")
-    private String remark;
-
-    /** DELETE_FLAG */
-    @Schema(description = "DELETE_FLAG")
-    @TableLogic
-    @TableField(fill = FieldFill.INSERT)
-    private String deleteFlag;
-}

+ 0 - 103
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo/service/impl/DemoServiceImpl.java

@@ -1,103 +0,0 @@
-/*
- * Copyright [2022] [https://www.xiaonuo.vip]
- *
- * Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
- *
- * 1.请不要删除和修改根目录下的LICENSE文件。
- * 2.请不要删除和修改Snowy源码头部的版权声明。
- * 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
- * 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
- * 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
- * 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
- */
-package vip.xiaonuo.biz.modular.demo.service.impl;
-
-import cn.hutool.core.bean.BeanUtil;
-import cn.hutool.core.collection.CollStreamUtil;
-import cn.hutool.core.util.ObjectUtil;
-import cn.hutool.core.util.StrUtil;
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-import vip.xiaonuo.common.enums.CommonSortOrderEnum;
-import vip.xiaonuo.common.exception.CommonException;
-import vip.xiaonuo.common.page.CommonPageRequest;
-import vip.xiaonuo.biz.modular.demo.entity.Demo;
-import vip.xiaonuo.biz.modular.demo.mapper.DemoMapper;
-import vip.xiaonuo.biz.modular.demo.param.DemoAddParam;
-import vip.xiaonuo.biz.modular.demo.param.DemoEditParam;
-import vip.xiaonuo.biz.modular.demo.param.DemoIdParam;
-import vip.xiaonuo.biz.modular.demo.param.DemoPageParam;
-import vip.xiaonuo.biz.modular.demo.service.DemoService;
-
-import java.util.List;
-
-/**
- * 例子Service接口实现类
- *
- * @author 曹钊瑞
- * @date  2024/07/01 17:46
- **/
-@Service
-public class DemoServiceImpl extends ServiceImpl<DemoMapper, Demo> implements DemoService {
-
-    @Override
-    public Page<Demo> page(DemoPageParam demoPageParam) {
-        QueryWrapper<Demo> queryWrapper = new QueryWrapper<Demo>().checkSqlInjection();
-        if(ObjectUtil.isNotEmpty(demoPageParam.getName())) {
-            queryWrapper.lambda().like(Demo::getName, demoPageParam.getName());
-        }
-        if(ObjectUtil.isNotEmpty(demoPageParam.getAge())) {
-            queryWrapper.lambda().eq(Demo::getAge, demoPageParam.getAge());
-        }
-        if(ObjectUtil.isNotEmpty(demoPageParam.getSex())) {
-            queryWrapper.lambda().eq(Demo::getSex, demoPageParam.getSex());
-        }
-        if(ObjectUtil.isAllNotEmpty(demoPageParam.getSortField(), demoPageParam.getSortOrder())) {
-            CommonSortOrderEnum.validate(demoPageParam.getSortOrder());
-            queryWrapper.orderBy(true, demoPageParam.getSortOrder().equals(CommonSortOrderEnum.ASC.getValue()),
-                    StrUtil.toUnderlineCase(demoPageParam.getSortField()));
-        } else {
-            queryWrapper.lambda().orderByAsc(Demo::getId);
-        }
-        return this.page(CommonPageRequest.defaultPage(), queryWrapper);
-    }
-
-    @Transactional(rollbackFor = Exception.class)
-    @Override
-    public void add(DemoAddParam demoAddParam) {
-        Demo demo = BeanUtil.toBean(demoAddParam, Demo.class);
-        this.save(demo);
-    }
-
-    @Transactional(rollbackFor = Exception.class)
-    @Override
-    public void edit(DemoEditParam demoEditParam) {
-        Demo demo = this.queryEntity(demoEditParam.getId());
-        BeanUtil.copyProperties(demoEditParam, demo);
-        this.updateById(demo);
-    }
-
-    @Transactional(rollbackFor = Exception.class)
-    @Override
-    public void delete(List<DemoIdParam> demoIdParamList) {
-        // 执行删除
-        this.removeByIds(CollStreamUtil.toList(demoIdParamList, DemoIdParam::getId));
-    }
-
-    @Override
-    public Demo detail(DemoIdParam demoIdParam) {
-        return this.queryEntity(demoIdParam.getId());
-    }
-
-    @Override
-    public Demo queryEntity(String id) {
-        Demo demo = this.getById(id);
-        if(ObjectUtil.isEmpty(demo)) {
-            throw new CommonException("例子不存在,id值为:{}", id);
-        }
-        return demo;
-    }
-}

+ 173 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo1/controller/Demo1Controller.java

@@ -0,0 +1,173 @@
+/*
+ * Copyright [2022] [https://www.xiaonuo.vip]
+ *
+ * Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
+ *
+ * 1.请不要删除和修改根目录下的LICENSE文件。
+ * 2.请不要删除和修改Snowy源码头部的版权声明。
+ * 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
+ * 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
+ * 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
+ * 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
+ */
+package vip.xiaonuo.biz.modular.demo1.controller;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import io.swagger.v3.oas.annotations.Operation;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+import vip.xiaonuo.common.annotation.CommonLog;
+import vip.xiaonuo.common.pojo.CommonResult;
+import vip.xiaonuo.biz.modular.demo1.entity.Demo1;
+import vip.xiaonuo.biz.modular.demo1.param.Demo1AddParam;
+import vip.xiaonuo.biz.modular.demo1.param.Demo1EditParam;
+import vip.xiaonuo.biz.modular.demo1.param.Demo1IdParam;
+import vip.xiaonuo.biz.modular.demo1.param.Demo1PageParam;
+import vip.xiaonuo.biz.modular.demo1.service.Demo1Service;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.annotation.Resource;
+import jakarta.validation.Valid;
+import jakarta.validation.constraints.NotEmpty;
+import java.util.List;
+import java.io.IOException;
+import com.alibaba.excel.EasyExcel;
+import com.alibaba.fastjson.JSON;
+import java.net.URLEncoder;
+import java.util.HashMap;
+
+/**
+ * 内嵌表单控制器
+ *
+ * @author 曹钊瑞
+ * @date  2024/07/02 18:06
+ */
+@Tag(name = "内嵌表单控制器")
+@RestController
+@Validated
+public class Demo1Controller {
+
+    @Resource
+    private Demo1Service demo1Service;
+
+    /**
+     * 获取内嵌表单分页
+     *
+     * @author 曹钊瑞
+     * @date  2024/07/02 18:06
+     */
+    @Operation(summary = "获取内嵌表单分页")
+    @SaCheckPermission("/biz/demo1/page")
+    @GetMapping("/biz/demo1/page")
+    public CommonResult<Page<Demo1>> page(Demo1PageParam demo1PageParam) {
+        return CommonResult.data(demo1Service.page(demo1PageParam));
+    }
+
+    /**
+     * 添加内嵌表单
+     *
+     * @author 曹钊瑞
+     * @date  2024/07/02 18:06
+     */
+    @Operation(summary = "添加内嵌表单")
+    @CommonLog("添加内嵌表单")
+    @SaCheckPermission("/biz/demo1/add")
+    @PostMapping("/biz/demo1/add")
+    public CommonResult<String> add(@RequestBody @Valid Demo1AddParam demo1AddParam) {
+        demo1Service.add(demo1AddParam);
+        return CommonResult.ok();
+    }
+
+    /**
+     * 编辑内嵌表单
+     *
+     * @author 曹钊瑞
+     * @date  2024/07/02 18:06
+     */
+    @Operation(summary = "编辑内嵌表单")
+    @CommonLog("编辑内嵌表单")
+    @SaCheckPermission("/biz/demo1/edit")
+    @PostMapping("/biz/demo1/edit")
+    public CommonResult<String> edit(@RequestBody @Valid Demo1EditParam demo1EditParam) {
+        demo1Service.edit(demo1EditParam);
+        return CommonResult.ok();
+    }
+
+    /**
+     * 导出内嵌表单
+     *
+     * @author 曹钊瑞
+     * @date  2024/07/02 18:06
+     */
+    @Operation(summary = "导出内嵌表单")
+    @CommonLog("导出内嵌表单")
+    @SaCheckPermission("/biz/demo1/export")
+    @PostMapping("/biz/demo1/export")
+    public void export(@RequestBody @Valid Demo1PageParam demo1PageParam, HttpServletResponse response) {
+        Page<Demo1> page =  demo1Service.page(demo1PageParam);
+        List<Demo1> records = page.getRecords();
+        exportExcel(response,Demo1.class,records,"内嵌表单");
+    }
+
+
+    /**
+     * 导出表格数据
+     * @param cl       表格字段实体类
+     * @param data     查询数据
+     * @param sheetName  表格名称
+     */
+    public void exportExcel(HttpServletResponse response, Class cl, List data, String sheetName){
+        HashMap<String, String> map = new HashMap<>();
+        try {
+            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
+            response.setCharacterEncoding("utf-8");
+            String fileName = URLEncoder.encode(sheetName, "UTF-8").replaceAll("\\+", "%20");
+            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
+            EasyExcel.write(response.getOutputStream(), cl).autoCloseStream(Boolean.FALSE).sheet(sheetName).doWrite(data);
+        } catch (IOException e) {
+            response.reset();
+            response.setContentType("application/json");
+            response.setCharacterEncoding("utf-8");
+            map.put("status", "failure");
+            map.put("message", "下载文件失败" + e.getMessage());
+            try {
+                response.getWriter().println(JSON.toJSONString(map));
+            } catch (IOException ex) {
+                ex.printStackTrace();
+            }
+        }
+    }
+
+    /**
+     * 删除内嵌表单
+     *
+     * @author 曹钊瑞
+     * @date  2024/07/02 18:06
+     */
+    @Operation(summary = "删除内嵌表单")
+    @CommonLog("删除内嵌表单")
+    @SaCheckPermission("/biz/demo1/delete")
+    @PostMapping("/biz/demo1/delete")
+    public CommonResult<String> delete(@RequestBody @Valid @NotEmpty(message = "集合不能为空")
+                                                   List<Demo1IdParam> demo1IdParamList) {
+        demo1Service.delete(demo1IdParamList);
+        return CommonResult.ok();
+    }
+
+    /**
+     * 获取内嵌表单详情
+     *
+     * @author 曹钊瑞
+     * @date  2024/07/02 18:06
+     */
+    @Operation(summary = "获取内嵌表单详情")
+    @SaCheckPermission("/biz/demo1/detail")
+    @GetMapping("/biz/demo1/detail")
+    public CommonResult<Demo1> detail(@Valid Demo1IdParam demo1IdParam) {
+        return CommonResult.data(demo1Service.detail(demo1IdParam));
+    }
+}

+ 158 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo1/entity/Demo1.java

@@ -0,0 +1,158 @@
+/*
+ * Copyright [2022] [https://www.xiaonuo.vip]
+ *
+ * Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
+ *
+ * 1.请不要删除和修改根目录下的LICENSE文件。
+ * 2.请不要删除和修改Snowy源码头部的版权声明。
+ * 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
+ * 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
+ * 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
+ * 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
+ */
+package vip.xiaonuo.biz.modular.demo1.entity;
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.annotation.write.style.ColumnWidth;
+import com.baomidou.mybatisplus.annotation.*;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Getter;
+import lombok.Setter;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 内嵌表单实体
+ *
+ * @author 曹钊瑞
+ * @date  2024/07/02 18:06
+ **/
+@Getter
+@Setter
+@TableName("demo")
+public class Demo1 {
+
+    /** ID */
+    @TableId
+    @Schema(description = "ID")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 0,value = "ID")
+    private String id;
+
+    /** NAME */
+    @Schema(description = "NAME")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 1,value = "NAME")
+    private String name;
+
+    /** AGE */
+    @Schema(description = "AGE")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 2,value = "AGE")
+    private String age;
+
+    /** SEX */
+    @Schema(description = "SEX")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 3,value = "SEX")
+    private String sex;
+
+    /** REMARK */
+    @Schema(description = "REMARK")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 4,value = "REMARK")
+    private String remark;
+
+    /** DELETE_FLAG */
+    @Schema(description = "DELETE_FLAG")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 5,value = "DELETE_FLAG")
+    @TableLogic
+    @TableField(fill = FieldFill.INSERT)
+    private String deleteFlag;
+
+    /** P1 */
+    @Schema(description = "P1")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 6,value = "P1")
+    private String p1;
+
+    /** P2 */
+    @Schema(description = "P2")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 7,value = "P2")
+    private String p2;
+
+    /** P3 */
+    @Schema(description = "P3")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 8,value = "P3")
+    private String p3;
+
+    /** P4 */
+    @Schema(description = "P4")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 9,value = "P4")
+    private String p4;
+
+    /** P5 */
+    @Schema(description = "P5")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 10,value = "P5")
+    private String p5;
+
+    /** P6 */
+    @Schema(description = "P6")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 11,value = "P6")
+    private String p6;
+
+    /** P7 */
+    @Schema(description = "P7")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 12,value = "P7")
+    private String p7;
+
+    /** P8 */
+    @Schema(description = "P8")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 13,value = "P8")
+    private String p8;
+
+    /** P9 */
+    @Schema(description = "P9")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 14,value = "P9")
+    private String p9;
+
+    /** P10 */
+    @Schema(description = "P10")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 15,value = "P10")
+    private String p10;
+
+    /** CREATE_TIME */
+    @Schema(description = "CREATE_TIME")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 16,value = "CREATE_TIME")
+    @TableField(fill = FieldFill.INSERT)
+    private Date createTime;
+
+    /** CREATE_BY */
+    @Schema(description = "CREATE_BY")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 17,value = "CREATE_BY")
+    private String createBy;
+
+    /** UPDATE_TIME */
+    @Schema(description = "UPDATE_TIME")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 18,value = "UPDATE_TIME")
+    @TableField(fill = FieldFill.UPDATE)
+    private Date updateTime;
+
+    /** UPDATE_BY */
+    @Schema(description = "UPDATE_BY")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 19,value = "UPDATE_BY")
+    private String updateBy;
+}

+ 5 - 5
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo/enums/DemoEnum.java

@@ -10,25 +10,25 @@
  * 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
  * 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
  */
-package vip.xiaonuo.biz.modular.demo.enums;
+package vip.xiaonuo.biz.modular.demo1.enums;
 
 import lombok.Getter;
 
 /**
- * 例子枚举
+ * 内嵌表单枚举
  *
  * @author 曹钊瑞
- * @date  2024/07/01 17:46
+ * @date  2024/07/02 18:06
  **/
 @Getter
-public enum DemoEnum {
+public enum Demo1Enum {
 
     /** 测试 */
     TEST("TEST");
 
     private final String value;
 
-    DemoEnum(String value) {
+    Demo1Enum(String value) {
         this.value = value;
     }
 }

+ 5 - 5
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo/mapper/DemoMapper.java

@@ -10,16 +10,16 @@
  * 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
  * 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
  */
-package vip.xiaonuo.biz.modular.demo.mapper;
+package vip.xiaonuo.biz.modular.demo1.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import vip.xiaonuo.biz.modular.demo.entity.Demo;
+import vip.xiaonuo.biz.modular.demo1.entity.Demo1;
 
 /**
- * 例子Mapper接口
+ * 内嵌表单Mapper接口
  *
  * @author 曹钊瑞
- * @date  2024/07/01 17:46
+ * @date  2024/07/02 18:06
  **/
-public interface DemoMapper extends BaseMapper<Demo> {
+public interface Demo1Mapper extends BaseMapper<Demo1> {
 }

+ 1 - 1
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo/mapper/mapping/DemoMapper.xml

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="vip.xiaonuo.biz.modular.demo.mapper.DemoMapper">
+<mapper namespace="vip.xiaonuo.biz.modular.demo1.mapper.Demo1Mapper">
 
 </mapper>

+ 44 - 4
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo/param/DemoAddParam.java

@@ -10,7 +10,7 @@
  * 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
  * 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
  */
-package vip.xiaonuo.biz.modular.demo.param;
+package vip.xiaonuo.biz.modular.demo1.param;
 
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Getter;
@@ -22,14 +22,14 @@ import java.math.BigDecimal;
 import java.util.Date;
 
 /**
- * 例子添加参数
+ * 内嵌表单添加参数
  *
  * @author 曹钊瑞
- * @date  2024/07/01 17:46
+ * @date  2024/07/02 18:06
  **/
 @Getter
 @Setter
-public class DemoAddParam {
+public class Demo1AddParam {
 
     /** NAME */
     @Schema(description = "NAME", requiredMode = Schema.RequiredMode.REQUIRED)
@@ -50,4 +50,44 @@ public class DemoAddParam {
     @Schema(description = "REMARK")
     private String remark;
 
+    /** P1 */
+    @Schema(description = "P1")
+    private String p1;
+
+    /** P2 */
+    @Schema(description = "P2")
+    private String p2;
+
+    /** P3 */
+    @Schema(description = "P3")
+    private String p3;
+
+    /** P4 */
+    @Schema(description = "P4")
+    private String p4;
+
+    /** P5 */
+    @Schema(description = "P5")
+    private String p5;
+
+    /** P6 */
+    @Schema(description = "P6")
+    private String p6;
+
+    /** P7 */
+    @Schema(description = "P7")
+    private String p7;
+
+    /** P8 */
+    @Schema(description = "P8")
+    private String p8;
+
+    /** P9 */
+    @Schema(description = "P9")
+    private String p9;
+
+    /** P10 */
+    @Schema(description = "P10")
+    private String p10;
+
 }

+ 44 - 4
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo/param/DemoEditParam.java

@@ -10,7 +10,7 @@
  * 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
  * 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
  */
-package vip.xiaonuo.biz.modular.demo.param;
+package vip.xiaonuo.biz.modular.demo1.param;
 
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Getter;
@@ -22,14 +22,14 @@ import java.math.BigDecimal;
 import java.util.Date;
 
 /**
- * 例子编辑参数
+ * 内嵌表单编辑参数
  *
  * @author 曹钊瑞
- * @date  2024/07/01 17:46
+ * @date  2024/07/02 18:06
  **/
 @Getter
 @Setter
-public class DemoEditParam {
+public class Demo1EditParam {
 
     /** ID */
     @Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED)
@@ -55,4 +55,44 @@ public class DemoEditParam {
     @Schema(description = "REMARK")
     private String remark;
 
+    /** P1 */
+    @Schema(description = "P1")
+    private String p1;
+
+    /** P2 */
+    @Schema(description = "P2")
+    private String p2;
+
+    /** P3 */
+    @Schema(description = "P3")
+    private String p3;
+
+    /** P4 */
+    @Schema(description = "P4")
+    private String p4;
+
+    /** P5 */
+    @Schema(description = "P5")
+    private String p5;
+
+    /** P6 */
+    @Schema(description = "P6")
+    private String p6;
+
+    /** P7 */
+    @Schema(description = "P7")
+    private String p7;
+
+    /** P8 */
+    @Schema(description = "P8")
+    private String p8;
+
+    /** P9 */
+    @Schema(description = "P9")
+    private String p9;
+
+    /** P10 */
+    @Schema(description = "P10")
+    private String p10;
+
 }

+ 4 - 4
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo/param/DemoIdParam.java

@@ -10,7 +10,7 @@
  * 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
  * 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
  */
-package vip.xiaonuo.biz.modular.demo.param;
+package vip.xiaonuo.biz.modular.demo1.param;
 
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Getter;
@@ -19,14 +19,14 @@ import lombok.Setter;
 import jakarta.validation.constraints.NotBlank;
 
 /**
- * 例子Id参数
+ * 内嵌表单Id参数
  *
  * @author 曹钊瑞
- * @date  2024/07/01 17:46
+ * @date  2024/07/02 18:06
  **/
 @Getter
 @Setter
-public class DemoIdParam {
+public class Demo1IdParam {
 
     /** ID */
     @Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED)

+ 40 - 4
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo/param/DemoPageParam.java

@@ -10,7 +10,7 @@
  * 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
  * 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
  */
-package vip.xiaonuo.biz.modular.demo.param;
+package vip.xiaonuo.biz.modular.demo1.param;
 
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Getter;
@@ -19,14 +19,14 @@ import java.math.BigDecimal;
 import java.util.Date;
 
 /**
- * 例子查询参数
+ * 内嵌表单查询参数
  *
  * @author 曹钊瑞
- * @date  2024/07/01 17:46
+ * @date  2024/07/02 18:06
  **/
 @Getter
 @Setter
-public class DemoPageParam {
+public class Demo1PageParam {
 
     /** 当前页 */
     @Schema(description = "当前页码")
@@ -60,4 +60,40 @@ public class DemoPageParam {
     @Schema(description = "SEX")
     private String sex;
 
+    /** REMARK */
+    @Schema(description = "REMARK")
+    private String remark;
+
+    /** P1 */
+    @Schema(description = "P1")
+    private String p1;
+
+    /** P2 */
+    @Schema(description = "P2")
+    private String p2;
+
+    /** P3 */
+    @Schema(description = "P3")
+    private String p3;
+
+    /** P4 */
+    @Schema(description = "P4")
+    private String p4;
+
+    /** CREATE_TIME开始 */
+    @Schema(description = "CREATE_TIME开始")
+    private String startCreateTime;
+
+    /** CREATE_TIME结束 */
+    @Schema(description = "CREATE_TIME结束")
+    private String endCreateTime;
+
+    /** UPDATE_TIME开始 */
+    @Schema(description = "UPDATE_TIME开始")
+    private String startUpdateTime;
+
+    /** UPDATE_TIME结束 */
+    @Schema(description = "UPDATE_TIME结束")
+    private String endUpdateTime;
+
 }

+ 27 - 27
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo/service/DemoService.java

@@ -10,71 +10,71 @@
  * 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
  * 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
  */
-package vip.xiaonuo.biz.modular.demo.service;
+package vip.xiaonuo.biz.modular.demo1.service;
 
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.IService;
-import vip.xiaonuo.biz.modular.demo.entity.Demo;
-import vip.xiaonuo.biz.modular.demo.param.DemoAddParam;
-import vip.xiaonuo.biz.modular.demo.param.DemoEditParam;
-import vip.xiaonuo.biz.modular.demo.param.DemoIdParam;
-import vip.xiaonuo.biz.modular.demo.param.DemoPageParam;
+import vip.xiaonuo.biz.modular.demo1.entity.Demo1;
+import vip.xiaonuo.biz.modular.demo1.param.Demo1AddParam;
+import vip.xiaonuo.biz.modular.demo1.param.Demo1EditParam;
+import vip.xiaonuo.biz.modular.demo1.param.Demo1IdParam;
+import vip.xiaonuo.biz.modular.demo1.param.Demo1PageParam;
 
 import java.util.List;
 
 /**
- * 例子Service接口
+ * 内嵌表单Service接口
  *
  * @author 曹钊瑞
- * @date  2024/07/01 17:46
+ * @date  2024/07/02 18:06
  **/
-public interface DemoService extends IService<Demo> {
+public interface Demo1Service extends IService<Demo1> {
 
     /**
-     * 获取例子分页
+     * 获取内嵌表单分页
      *
      * @author 曹钊瑞
-     * @date  2024/07/01 17:46
+     * @date  2024/07/02 18:06
      */
-    Page<Demo> page(DemoPageParam demoPageParam);
+    Page<Demo1> page(Demo1PageParam demo1PageParam);
 
     /**
-     * 添加例子
+     * 添加内嵌表单
      *
      * @author 曹钊瑞
-     * @date  2024/07/01 17:46
+     * @date  2024/07/02 18:06
      */
-    void add(DemoAddParam demoAddParam);
+    void add(Demo1AddParam demo1AddParam);
 
     /**
-     * 编辑例子
+     * 编辑内嵌表单
      *
      * @author 曹钊瑞
-     * @date  2024/07/01 17:46
+     * @date  2024/07/02 18:06
      */
-    void edit(DemoEditParam demoEditParam);
+    void edit(Demo1EditParam demo1EditParam);
 
     /**
-     * 删除例子
+     * 删除内嵌表单
      *
      * @author 曹钊瑞
-     * @date  2024/07/01 17:46
+     * @date  2024/07/02 18:06
      */
-    void delete(List<DemoIdParam> demoIdParamList);
+    void delete(List<Demo1IdParam> demo1IdParamList);
 
     /**
-     * 获取例子详情
+     * 获取内嵌表单详情
      *
      * @author 曹钊瑞
-     * @date  2024/07/01 17:46
+     * @date  2024/07/02 18:06
      */
-    Demo detail(DemoIdParam demoIdParam);
+    Demo1 detail(Demo1IdParam demo1IdParam);
 
     /**
-     * 获取例子详情
+     * 获取内嵌表单详情
      *
      * @author 曹钊瑞
-     * @date  2024/07/01 17:46
+     * @date  2024/07/02 18:06
      **/
-    Demo queryEntity(String id);
+    Demo1 queryEntity(String id);
 }

+ 124 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo1/service/impl/Demo1ServiceImpl.java

@@ -0,0 +1,124 @@
+/*
+ * Copyright [2022] [https://www.xiaonuo.vip]
+ *
+ * Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
+ *
+ * 1.请不要删除和修改根目录下的LICENSE文件。
+ * 2.请不要删除和修改Snowy源码头部的版权声明。
+ * 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
+ * 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
+ * 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
+ * 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
+ */
+package vip.xiaonuo.biz.modular.demo1.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollStreamUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import vip.xiaonuo.common.enums.CommonSortOrderEnum;
+import vip.xiaonuo.common.exception.CommonException;
+import vip.xiaonuo.common.page.CommonPageRequest;
+import vip.xiaonuo.biz.modular.demo1.entity.Demo1;
+import vip.xiaonuo.biz.modular.demo1.mapper.Demo1Mapper;
+import vip.xiaonuo.biz.modular.demo1.param.Demo1AddParam;
+import vip.xiaonuo.biz.modular.demo1.param.Demo1EditParam;
+import vip.xiaonuo.biz.modular.demo1.param.Demo1IdParam;
+import vip.xiaonuo.biz.modular.demo1.param.Demo1PageParam;
+import vip.xiaonuo.biz.modular.demo1.service.Demo1Service;
+
+import java.util.List;
+
+/**
+ * 内嵌表单Service接口实现类
+ *
+ * @author 曹钊瑞
+ * @date  2024/07/02 18:06
+ **/
+@Service
+public class Demo1ServiceImpl extends ServiceImpl<Demo1Mapper, Demo1> implements Demo1Service {
+
+    @Override
+    public Page<Demo1> page(Demo1PageParam demo1PageParam) {
+        QueryWrapper<Demo1> queryWrapper = new QueryWrapper<Demo1>().checkSqlInjection();
+        if(ObjectUtil.isNotEmpty(demo1PageParam.getName())) {
+            queryWrapper.lambda().like(Demo1::getName, demo1PageParam.getName());
+        }
+        if(ObjectUtil.isNotEmpty(demo1PageParam.getAge())) {
+            queryWrapper.lambda().le(Demo1::getAge, demo1PageParam.getAge());
+        }
+        if(ObjectUtil.isNotEmpty(demo1PageParam.getSex())) {
+            queryWrapper.lambda().eq(Demo1::getSex, demo1PageParam.getSex());
+        }
+        if(ObjectUtil.isNotEmpty(demo1PageParam.getRemark())) {
+            queryWrapper.lambda().like(Demo1::getRemark, demo1PageParam.getRemark());
+        }
+        if(ObjectUtil.isNotEmpty(demo1PageParam.getP1())) {
+            queryWrapper.lambda().like(Demo1::getP1, demo1PageParam.getP1());
+        }
+        if(ObjectUtil.isNotEmpty(demo1PageParam.getP2())) {
+            queryWrapper.lambda().like(Demo1::getP2, demo1PageParam.getP2());
+        }
+        if(ObjectUtil.isNotEmpty(demo1PageParam.getP3())) {
+            queryWrapper.lambda().like(Demo1::getP3, demo1PageParam.getP3());
+        }
+        if(ObjectUtil.isNotEmpty(demo1PageParam.getP4())) {
+            queryWrapper.lambda().like(Demo1::getP4, demo1PageParam.getP4());
+        }
+        if(ObjectUtil.isNotEmpty(demo1PageParam.getStartCreateTime()) && ObjectUtil.isNotEmpty(demo1PageParam.getEndCreateTime())) {
+            queryWrapper.lambda().between(Demo1::getCreateTime, demo1PageParam.getStartCreateTime(), demo1PageParam.getEndCreateTime());
+        }
+        if(ObjectUtil.isNotEmpty(demo1PageParam.getStartUpdateTime()) && ObjectUtil.isNotEmpty(demo1PageParam.getEndUpdateTime())) {
+            queryWrapper.lambda().between(Demo1::getUpdateTime, demo1PageParam.getStartUpdateTime(), demo1PageParam.getEndUpdateTime());
+        }
+        if(ObjectUtil.isAllNotEmpty(demo1PageParam.getSortField(), demo1PageParam.getSortOrder())) {
+            CommonSortOrderEnum.validate(demo1PageParam.getSortOrder());
+            queryWrapper.orderBy(true, demo1PageParam.getSortOrder().equals(CommonSortOrderEnum.ASC.getValue()),
+                    StrUtil.toUnderlineCase(demo1PageParam.getSortField()));
+        } else {
+            queryWrapper.lambda().orderByAsc(Demo1::getId);
+        }
+        return this.page(CommonPageRequest.defaultPage(), queryWrapper);
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void add(Demo1AddParam demo1AddParam) {
+        Demo1 demo1 = BeanUtil.toBean(demo1AddParam, Demo1.class);
+        this.save(demo1);
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void edit(Demo1EditParam demo1EditParam) {
+        Demo1 demo1 = this.queryEntity(demo1EditParam.getId());
+        BeanUtil.copyProperties(demo1EditParam, demo1);
+        this.updateById(demo1);
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void delete(List<Demo1IdParam> demo1IdParamList) {
+        // 执行删除
+        this.removeByIds(CollStreamUtil.toList(demo1IdParamList, Demo1IdParam::getId));
+    }
+
+    @Override
+    public Demo1 detail(Demo1IdParam demo1IdParam) {
+        return this.queryEntity(demo1IdParam.getId());
+    }
+
+    @Override
+    public Demo1 queryEntity(String id) {
+        Demo1 demo1 = this.getById(id);
+        if(ObjectUtil.isEmpty(demo1)) {
+            throw new CommonException("内嵌表单不存在,id值为:{}", id);
+        }
+        return demo1;
+    }
+}

+ 72 - 22
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo2/controller/Demo2Controller.java

@@ -29,19 +29,24 @@ import vip.xiaonuo.biz.modular.demo2.param.Demo2EditParam;
 import vip.xiaonuo.biz.modular.demo2.param.Demo2IdParam;
 import vip.xiaonuo.biz.modular.demo2.param.Demo2PageParam;
 import vip.xiaonuo.biz.modular.demo2.service.Demo2Service;
-
+import jakarta.servlet.http.HttpServletResponse;
 import jakarta.annotation.Resource;
 import jakarta.validation.Valid;
 import jakarta.validation.constraints.NotEmpty;
 import java.util.List;
+import java.io.IOException;
+import com.alibaba.excel.EasyExcel;
+import com.alibaba.fastjson.JSON;
+import java.net.URLEncoder;
+import java.util.HashMap;
 
 /**
- * 例子2控制器
+ * 弹窗表单控制器
  *
  * @author 曹钊瑞
- * @date  2024/07/01 17:47
+ * @date  2024/07/02 18:06
  */
-@Tag(name = "例子2控制器")
+@Tag(name = "弹窗表单控制器")
 @RestController
 @Validated
 public class Demo2Controller {
@@ -50,12 +55,12 @@ public class Demo2Controller {
     private Demo2Service demo2Service;
 
     /**
-     * 获取例子2分页
+     * 获取弹窗表单分页
      *
      * @author 曹钊瑞
-     * @date  2024/07/01 17:47
+     * @date  2024/07/02 18:06
      */
-    @Operation(summary = "获取例子2分页")
+    @Operation(summary = "获取弹窗表单分页")
     @SaCheckPermission("/biz/demo2/page")
     @GetMapping("/biz/demo2/page")
     public CommonResult<Page<Demo2>> page(Demo2PageParam demo2PageParam) {
@@ -63,13 +68,13 @@ public class Demo2Controller {
     }
 
     /**
-     * 添加例子2
+     * 添加弹窗表单
      *
      * @author 曹钊瑞
-     * @date  2024/07/01 17:47
+     * @date  2024/07/02 18:06
      */
-    @Operation(summary = "添加例子2")
-    @CommonLog("添加例子2")
+    @Operation(summary = "添加弹窗表单")
+    @CommonLog("添加弹窗表单")
     @SaCheckPermission("/biz/demo2/add")
     @PostMapping("/biz/demo2/add")
     public CommonResult<String> add(@RequestBody @Valid Demo2AddParam demo2AddParam) {
@@ -78,13 +83,13 @@ public class Demo2Controller {
     }
 
     /**
-     * 编辑例子2
+     * 编辑弹窗表单
      *
      * @author 曹钊瑞
-     * @date  2024/07/01 17:47
+     * @date  2024/07/02 18:06
      */
-    @Operation(summary = "编辑例子2")
-    @CommonLog("编辑例子2")
+    @Operation(summary = "编辑弹窗表单")
+    @CommonLog("编辑弹窗表单")
     @SaCheckPermission("/biz/demo2/edit")
     @PostMapping("/biz/demo2/edit")
     public CommonResult<String> edit(@RequestBody @Valid Demo2EditParam demo2EditParam) {
@@ -93,13 +98,58 @@ public class Demo2Controller {
     }
 
     /**
-     * 删除例子2
+     * 导出弹窗表单
+     *
+     * @author 曹钊瑞
+     * @date  2024/07/02 18:06
+     */
+    @Operation(summary = "导出弹窗表单")
+    @CommonLog("导出弹窗表单")
+    @SaCheckPermission("/biz/demo2/export")
+    @PostMapping("/biz/demo2/export")
+    public void export(@RequestBody @Valid Demo2PageParam demo2PageParam, HttpServletResponse response) {
+        Page<Demo2> page =  demo2Service.page(demo2PageParam);
+        List<Demo2> records = page.getRecords();
+        exportExcel(response,Demo2.class,records,"弹窗表单");
+    }
+
+
+    /**
+     * 导出表格数据
+     * @param cl       表格字段实体类
+     * @param data     查询数据
+     * @param sheetName  表格名称
+     */
+    public void exportExcel(HttpServletResponse response, Class cl, List data, String sheetName){
+        HashMap<String, String> map = new HashMap<>();
+        try {
+            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
+            response.setCharacterEncoding("utf-8");
+            String fileName = URLEncoder.encode(sheetName, "UTF-8").replaceAll("\\+", "%20");
+            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
+            EasyExcel.write(response.getOutputStream(), cl).autoCloseStream(Boolean.FALSE).sheet(sheetName).doWrite(data);
+        } catch (IOException e) {
+            response.reset();
+            response.setContentType("application/json");
+            response.setCharacterEncoding("utf-8");
+            map.put("status", "failure");
+            map.put("message", "下载文件失败" + e.getMessage());
+            try {
+                response.getWriter().println(JSON.toJSONString(map));
+            } catch (IOException ex) {
+                ex.printStackTrace();
+            }
+        }
+    }
+
+    /**
+     * 删除弹窗表单
      *
      * @author 曹钊瑞
-     * @date  2024/07/01 17:47
+     * @date  2024/07/02 18:06
      */
-    @Operation(summary = "删除例子2")
-    @CommonLog("删除例子2")
+    @Operation(summary = "删除弹窗表单")
+    @CommonLog("删除弹窗表单")
     @SaCheckPermission("/biz/demo2/delete")
     @PostMapping("/biz/demo2/delete")
     public CommonResult<String> delete(@RequestBody @Valid @NotEmpty(message = "集合不能为空")
@@ -109,12 +159,12 @@ public class Demo2Controller {
     }
 
     /**
-     * 获取例子2详情
+     * 获取弹窗表单详情
      *
      * @author 曹钊瑞
-     * @date  2024/07/01 17:47
+     * @date  2024/07/02 18:06
      */
-    @Operation(summary = "获取例子2详情")
+    @Operation(summary = "获取弹窗表单详情")
     @SaCheckPermission("/biz/demo2/detail")
     @GetMapping("/biz/demo2/detail")
     public CommonResult<Demo2> detail(@Valid Demo2IdParam demo2IdParam) {

+ 102 - 3
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo2/entity/Demo2.java

@@ -11,7 +11,8 @@
  * 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
  */
 package vip.xiaonuo.biz.modular.demo2.entity;
-
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.annotation.write.style.ColumnWidth;
 import com.baomidou.mybatisplus.annotation.*;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Getter;
@@ -20,10 +21,10 @@ import java.math.BigDecimal;
 import java.util.Date;
 
 /**
- * 例子2实体
+ * 弹窗表单实体
  *
  * @author 曹钊瑞
- * @date  2024/07/01 17:47
+ * @date  2024/07/02 18:06
  **/
 @Getter
 @Setter
@@ -33,27 +34,125 @@ public class Demo2 {
     /** ID */
     @TableId
     @Schema(description = "ID")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 0,value = "ID")
     private String id;
 
     /** NAME */
     @Schema(description = "NAME")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 1,value = "NAME")
     private String name;
 
     /** AGE */
     @Schema(description = "AGE")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 2,value = "AGE")
     private String age;
 
     /** SEX */
     @Schema(description = "SEX")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 3,value = "SEX")
     private String sex;
 
     /** REMARK */
     @Schema(description = "REMARK")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 4,value = "REMARK")
     private String remark;
 
     /** DELETE_FLAG */
     @Schema(description = "DELETE_FLAG")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 5,value = "DELETE_FLAG")
     @TableLogic
     @TableField(fill = FieldFill.INSERT)
     private String deleteFlag;
+
+    /** P1 */
+    @Schema(description = "P1")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 6,value = "P1")
+    private String p1;
+
+    /** P2 */
+    @Schema(description = "P2")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 7,value = "P2")
+    private String p2;
+
+    /** P3 */
+    @Schema(description = "P3")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 8,value = "P3")
+    private String p3;
+
+    /** P4 */
+    @Schema(description = "P4")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 9,value = "P4")
+    private String p4;
+
+    /** P5 */
+    @Schema(description = "P5")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 10,value = "P5")
+    private String p5;
+
+    /** P6 */
+    @Schema(description = "P6")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 11,value = "P6")
+    private String p6;
+
+    /** P7 */
+    @Schema(description = "P7")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 12,value = "P7")
+    private String p7;
+
+    /** P8 */
+    @Schema(description = "P8")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 13,value = "P8")
+    private String p8;
+
+    /** P9 */
+    @Schema(description = "P9")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 14,value = "P9")
+    private String p9;
+
+    /** P10 */
+    @Schema(description = "P10")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 15,value = "P10")
+    private String p10;
+
+    /** CREATE_TIME */
+    @Schema(description = "CREATE_TIME")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 16,value = "CREATE_TIME")
+    @TableField(fill = FieldFill.INSERT)
+    private Date createTime;
+
+    /** CREATE_BY */
+    @Schema(description = "CREATE_BY")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 17,value = "CREATE_BY")
+    private String createBy;
+
+    /** UPDATE_TIME */
+    @Schema(description = "UPDATE_TIME")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 18,value = "UPDATE_TIME")
+    @TableField(fill = FieldFill.UPDATE)
+    private Date updateTime;
+
+    /** UPDATE_BY */
+    @Schema(description = "UPDATE_BY")
+    @ColumnWidth(12)
+    @ExcelProperty(index = 19,value = "UPDATE_BY")
+    private String updateBy;
 }

+ 2 - 2
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo2/enums/Demo2Enum.java

@@ -15,10 +15,10 @@ package vip.xiaonuo.biz.modular.demo2.enums;
 import lombok.Getter;
 
 /**
- * 例子2枚举
+ * 弹窗表单枚举
  *
  * @author 曹钊瑞
- * @date  2024/07/01 17:47
+ * @date  2024/07/02 18:06
  **/
 @Getter
 public enum Demo2Enum {

+ 2 - 2
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo2/mapper/Demo2Mapper.java

@@ -16,10 +16,10 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import vip.xiaonuo.biz.modular.demo2.entity.Demo2;
 
 /**
- * 例子2Mapper接口
+ * 弹窗表单Mapper接口
  *
  * @author 曹钊瑞
- * @date  2024/07/01 17:47
+ * @date  2024/07/02 18:06
  **/
 public interface Demo2Mapper extends BaseMapper<Demo2> {
 }

+ 52 - 3
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo2/param/Demo2AddParam.java

@@ -22,17 +22,18 @@ import java.math.BigDecimal;
 import java.util.Date;
 
 /**
- * 例子2添加参数
+ * 弹窗表单添加参数
  *
  * @author 曹钊瑞
- * @date  2024/07/01 17:47
+ * @date  2024/07/02 18:06
  **/
 @Getter
 @Setter
 public class Demo2AddParam {
 
     /** NAME */
-    @Schema(description = "NAME")
+    @Schema(description = "NAME", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "name不能为空")
     private String name;
 
     /** AGE */
@@ -47,4 +48,52 @@ public class Demo2AddParam {
     @Schema(description = "REMARK")
     private String remark;
 
+    /** P1 */
+    @Schema(description = "P1")
+    private String p1;
+
+    /** P2 */
+    @Schema(description = "P2")
+    private String p2;
+
+    /** P3 */
+    @Schema(description = "P3")
+    private String p3;
+
+    /** P4 */
+    @Schema(description = "P4")
+    private String p4;
+
+    /** P5 */
+    @Schema(description = "P5")
+    private String p5;
+
+    /** P6 */
+    @Schema(description = "P6")
+    private String p6;
+
+    /** P7 */
+    @Schema(description = "P7")
+    private String p7;
+
+    /** P8 */
+    @Schema(description = "P8")
+    private String p8;
+
+    /** P9 */
+    @Schema(description = "P9")
+    private String p9;
+
+    /** P10 */
+    @Schema(description = "P10")
+    private String p10;
+
+    /** CREATE_BY */
+    @Schema(description = "CREATE_BY")
+    private String createBy;
+
+    /** UPDATE_BY */
+    @Schema(description = "UPDATE_BY")
+    private String updateBy;
+
 }

+ 52 - 3
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo2/param/Demo2EditParam.java

@@ -22,10 +22,10 @@ import java.math.BigDecimal;
 import java.util.Date;
 
 /**
- * 例子2编辑参数
+ * 弹窗表单编辑参数
  *
  * @author 曹钊瑞
- * @date  2024/07/01 17:47
+ * @date  2024/07/02 18:06
  **/
 @Getter
 @Setter
@@ -37,7 +37,8 @@ public class Demo2EditParam {
     private String id;
 
     /** NAME */
-    @Schema(description = "NAME")
+    @Schema(description = "NAME", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "name不能为空")
     private String name;
 
     /** AGE */
@@ -52,4 +53,52 @@ public class Demo2EditParam {
     @Schema(description = "REMARK")
     private String remark;
 
+    /** P1 */
+    @Schema(description = "P1")
+    private String p1;
+
+    /** P2 */
+    @Schema(description = "P2")
+    private String p2;
+
+    /** P3 */
+    @Schema(description = "P3")
+    private String p3;
+
+    /** P4 */
+    @Schema(description = "P4")
+    private String p4;
+
+    /** P5 */
+    @Schema(description = "P5")
+    private String p5;
+
+    /** P6 */
+    @Schema(description = "P6")
+    private String p6;
+
+    /** P7 */
+    @Schema(description = "P7")
+    private String p7;
+
+    /** P8 */
+    @Schema(description = "P8")
+    private String p8;
+
+    /** P9 */
+    @Schema(description = "P9")
+    private String p9;
+
+    /** P10 */
+    @Schema(description = "P10")
+    private String p10;
+
+    /** CREATE_BY */
+    @Schema(description = "CREATE_BY")
+    private String createBy;
+
+    /** UPDATE_BY */
+    @Schema(description = "UPDATE_BY")
+    private String updateBy;
+
 }

+ 2 - 2
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo2/param/Demo2IdParam.java

@@ -19,10 +19,10 @@ import lombok.Setter;
 import jakarta.validation.constraints.NotBlank;
 
 /**
- * 例子2Id参数
+ * 弹窗表单Id参数
  *
  * @author 曹钊瑞
- * @date  2024/07/01 17:47
+ * @date  2024/07/02 18:06
  **/
 @Getter
 @Setter

+ 2 - 14
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo2/param/Demo2PageParam.java

@@ -19,10 +19,10 @@ import java.math.BigDecimal;
 import java.util.Date;
 
 /**
- * 例子2查询参数
+ * 弹窗表单查询参数
  *
  * @author 曹钊瑞
- * @date  2024/07/01 17:47
+ * @date  2024/07/02 18:06
  **/
 @Getter
 @Setter
@@ -52,16 +52,4 @@ public class Demo2PageParam {
     @Schema(description = "NAME")
     private String name;
 
-    /** AGE */
-    @Schema(description = "AGE")
-    private String age;
-
-    /** SEX */
-    @Schema(description = "SEX")
-    private String sex;
-
-    /** REMARK */
-    @Schema(description = "REMARK")
-    private String remark;
-
 }

+ 14 - 14
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo2/service/Demo2Service.java

@@ -23,58 +23,58 @@ import vip.xiaonuo.biz.modular.demo2.param.Demo2PageParam;
 import java.util.List;
 
 /**
- * 例子2Service接口
+ * 弹窗表单Service接口
  *
  * @author 曹钊瑞
- * @date  2024/07/01 17:47
+ * @date  2024/07/02 18:06
  **/
 public interface Demo2Service extends IService<Demo2> {
 
     /**
-     * 获取例子2分页
+     * 获取弹窗表单分页
      *
      * @author 曹钊瑞
-     * @date  2024/07/01 17:47
+     * @date  2024/07/02 18:06
      */
     Page<Demo2> page(Demo2PageParam demo2PageParam);
 
     /**
-     * 添加例子2
+     * 添加弹窗表单
      *
      * @author 曹钊瑞
-     * @date  2024/07/01 17:47
+     * @date  2024/07/02 18:06
      */
     void add(Demo2AddParam demo2AddParam);
 
     /**
-     * 编辑例子2
+     * 编辑弹窗表单
      *
      * @author 曹钊瑞
-     * @date  2024/07/01 17:47
+     * @date  2024/07/02 18:06
      */
     void edit(Demo2EditParam demo2EditParam);
 
     /**
-     * 删除例子2
+     * 删除弹窗表单
      *
      * @author 曹钊瑞
-     * @date  2024/07/01 17:47
+     * @date  2024/07/02 18:06
      */
     void delete(List<Demo2IdParam> demo2IdParamList);
 
     /**
-     * 获取例子2详情
+     * 获取弹窗表单详情
      *
      * @author 曹钊瑞
-     * @date  2024/07/01 17:47
+     * @date  2024/07/02 18:06
      */
     Demo2 detail(Demo2IdParam demo2IdParam);
 
     /**
-     * 获取例子2详情
+     * 获取弹窗表单详情
      *
      * @author 曹钊瑞
-     * @date  2024/07/01 17:47
+     * @date  2024/07/02 18:06
      **/
     Demo2 queryEntity(String id);
 }

+ 3 - 12
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo2/service/impl/Demo2ServiceImpl.java

@@ -35,10 +35,10 @@ import vip.xiaonuo.biz.modular.demo2.service.Demo2Service;
 import java.util.List;
 
 /**
- * 例子2Service接口实现类
+ * 弹窗表单Service接口实现类
  *
  * @author 曹钊瑞
- * @date  2024/07/01 17:47
+ * @date  2024/07/02 18:06
  **/
 @Service
 public class Demo2ServiceImpl extends ServiceImpl<Demo2Mapper, Demo2> implements Demo2Service {
@@ -49,15 +49,6 @@ public class Demo2ServiceImpl extends ServiceImpl<Demo2Mapper, Demo2> implements
         if(ObjectUtil.isNotEmpty(demo2PageParam.getName())) {
             queryWrapper.lambda().like(Demo2::getName, demo2PageParam.getName());
         }
-        if(ObjectUtil.isNotEmpty(demo2PageParam.getAge())) {
-            queryWrapper.lambda().eq(Demo2::getAge, demo2PageParam.getAge());
-        }
-        if(ObjectUtil.isNotEmpty(demo2PageParam.getSex())) {
-            queryWrapper.lambda().eq(Demo2::getSex, demo2PageParam.getSex());
-        }
-        if(ObjectUtil.isNotEmpty(demo2PageParam.getRemark())) {
-            queryWrapper.lambda().like(Demo2::getRemark, demo2PageParam.getRemark());
-        }
         if(ObjectUtil.isAllNotEmpty(demo2PageParam.getSortField(), demo2PageParam.getSortOrder())) {
             CommonSortOrderEnum.validate(demo2PageParam.getSortOrder());
             queryWrapper.orderBy(true, demo2PageParam.getSortOrder().equals(CommonSortOrderEnum.ASC.getValue()),
@@ -99,7 +90,7 @@ public class Demo2ServiceImpl extends ServiceImpl<Demo2Mapper, Demo2> implements
     public Demo2 queryEntity(String id) {
         Demo2 demo2 = this.getById(id);
         if(ObjectUtil.isEmpty(demo2)) {
-            throw new CommonException("例子2不存在,id值为:{}", id);
+            throw new CommonException("弹窗表单不存在,id值为:{}", id);
         }
         return demo2;
     }

+ 1 - 1
snowy-plugin/snowy-plugin-gen/src/main/resources/frontend/Api.js.btl

@@ -23,7 +23,7 @@ export default {
 	},
 	// 导出${functionName}
     ${classNameFirstLower}Export(data) {
-        return request('export', data, 'get', {
+        return request('export', data, 'post', {
             responseType: 'blob'
         })
     },

+ 1 - 1
snowy-plugin/snowy-plugin-gen/src/main/resources/frontend/detail.vue.btl

@@ -3,7 +3,7 @@
 		<a-page-header
 			<% for(var i = 0; i < configList.~size; i++) { %>
             <% if(configList[i].needTableId) { %>
-            :title="formData.${configList[i].fieldNameCamelCase} ? '编辑${functionName}' : '增${functionName}'"
+            :title="formData.${configList[i].fieldNameCamelCase} ? '编辑${functionName}' : '增${functionName}'"
             <% } %>
             <% } %>
 			@back="onClose"

+ 1 - 1
snowy-plugin/snowy-plugin-gen/src/main/resources/frontend/form.vue.btl

@@ -2,7 +2,7 @@
 	<xn-form-container
 		<% for(var i = 0; i < configList.~size; i++) { %>
 		<% if(configList[i].needTableId) { %>
-		:title="formData.${configList[i].fieldNameCamelCase} ? '编辑${functionName}' : '增${functionName}'"
+		:title="formData.${configList[i].fieldNameCamelCase} ? '编辑${functionName}' : '增${functionName}'"
 		<% } %>
 		<% } %>
 		:width="700"

+ 1 - 0
snowy-plugin/snowy-plugin-gen/src/main/resources/frontend/index.vue.btl

@@ -231,6 +231,7 @@
 		}
 	}
 	const loadData = (parameter) => {
+        tableRef.value.clearSelected()
 		<% if (searchCount > 0) { %>
 		<% for(var i = 0; i < configList.~size; i++) { %>
 		<% if(!configList[i].needTableId && configList[i].needPage) { %>

+ 1 - 0
snowy-plugin/snowy-plugin-gen/src/main/resources/frontend/index_inside.vue.btl

@@ -232,6 +232,7 @@
 		}
 	}
 	const loadData = (parameter) => {
+        tableRef.value.clearSelected()
         <% if (searchCount > 0) { %>
         <% for(var i = 0; i < configList.~size; i++) { %>
         <% if(!configList[i].needTableId && configList[i].needPage) { %>