Browse Source

Merge remote-tracking branch 'origin/master'

heguanxun 9 months ago
parent
commit
b906857bd1
21 changed files with 505 additions and 1154 deletions
  1. 0 28
      snowy-admin-web/src/api/biz/demoApi.js
  2. 0 95
      snowy-admin-web/src/views/biz/demo/detail.vue
  3. 0 95
      snowy-admin-web/src/views/biz/demo/form.vue
  4. 0 146
      snowy-admin-web/src/views/biz/demo/index.vue
  5. 0 147
      snowy-admin-web/src/views/biz/demo/index_2.vue
  6. 20 3
      snowy-admin-web/src/views/gen/basic.vue
  7. 0 123
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo/controller/DemoController.java
  8. 0 59
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo/entity/Demo.java
  9. 0 34
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo/enums/DemoEnum.java
  10. 0 25
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo/mapper/DemoMapper.java
  11. 0 5
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo/mapper/mapping/DemoMapper.xml
  12. 0 53
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo/param/DemoAddParam.java
  13. 0 58
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo/param/DemoEditParam.java
  14. 0 35
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo/param/DemoIdParam.java
  15. 0 63
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo/param/DemoPageParam.java
  16. 0 80
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo/service/DemoService.java
  17. 0 103
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo/service/impl/DemoServiceImpl.java
  18. 4 0
      snowy-plugin/snowy-plugin-gen/src/main/java/vip/xiaonuo/gen/modular/basic/entity/GenBasic.java
  19. 16 2
      snowy-plugin/snowy-plugin-gen/src/main/java/vip/xiaonuo/gen/modular/basic/service/impl/GenBasicServiceImpl.java
  20. 184 0
      snowy-plugin/snowy-plugin-gen/src/main/resources/frontend/detail.vue.btl
  21. 281 0
      snowy-plugin/snowy-plugin-gen/src/main/resources/frontend/index_inside.vue.btl

+ 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/06/28 17:57
- **/
-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 - 95
snowy-admin-web/src/views/biz/demo/detail.vue

@@ -1,95 +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-button type="primary" @click="onSubmit" :loading="submitLoading">保存</a-button>
-		</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 - 95
snowy-admin-web/src/views/biz/demo/form.vue

@@ -1,95 +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-button type="primary" @click="onSubmit" :loading="submitLoading">保存</a-button>
-		</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 - 146
snowy-admin-web/src/views/biz/demo/index.vue

@@ -1,146 +0,0 @@
-<template>
-	<a-card :bordered="false">
-	33333
-		<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>

+ 0 - 147
snowy-admin-web/src/views/biz/demo/index_2.vue

@@ -1,147 +0,0 @@
-<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-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="demo2">
-	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 indexShow = ref(true)
-	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>

+ 20 - 3
snowy-admin-web/src/views/gen/basic.vue

@@ -173,6 +173,11 @@
 						<a-input-number class="xn-wd" v-model:value="formData.sortCode" :max="100" />
 					</a-form-item>
 				</a-col>
+				<a-col :span="8">
+					<a-form-item label="表单模式:" name="formMode">
+						<a-radio-group v-model:value="formData.formMode" :options="formModeOptions" />
+					</a-form-item>
+				</a-col>
 			</a-row>
 		</a-form>
 	</a-card>
@@ -232,6 +237,16 @@
 			value: 'N'
 		}
 	])
+	const formModeOptions = ref([
+		{
+			label: '弹窗',
+			value: 'dialog'
+		},
+		{
+			label: '内嵌',
+			value: 'inside'
+		}
+	])
 	// 打开抽屉
 	const onOpen = (record) => {
 		// 加载默认的模块
@@ -274,10 +289,11 @@
 					packageName: 'vip.xiaonuo',
 					moduleName: 'biz',
 					sortCode: 99,
-					tablePrefix: 'Y',
-					generateType: 'ZIP',
+					tablePrefix: 'N',
+					generateType: 'PRO',
 					formLayout: 'vertical',
-					gridWhether: 'N'
+					gridWhether: 'Y',
+					formMode: 'inside',
 				}
 			}
 		})
@@ -314,6 +330,7 @@
 		packageName: [required('请输入包名')],
 		sortCode: [required('请选择排序')],
 		formLayout: [required('请选择表单布局')],
+		formMode: [required('请选择表单模式')],
 		gridWhether: [required('请选择是否使用栅格')],
 		authorName: [required('请输入作者名')]
 	}

+ 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/06/28 17:57
- */
-@Tag(name = "例子控制器")
-@RestController
-@Validated
-public class DemoController {
-
-    @Resource
-    private DemoService demoService;
-
-    /**
-     * 获取例子分页
-     *
-     * @author 曹钊瑞
-     * @date  2024/06/28 17:57
-     */
-    @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/06/28 17:57
-     */
-    @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/06/28 17:57
-     */
-    @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/06/28 17:57
-     */
-    @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/06/28 17:57
-     */
-    @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/06/28 17:57
- **/
-@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 - 34
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/demo/enums/DemoEnum.java

@@ -1,34 +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.enums;
-
-import lombok.Getter;
-
-/**
- * 例子枚举
- *
- * @author 曹钊瑞
- * @date  2024/06/28 17:57
- **/
-@Getter
-public enum DemoEnum {
-
-    /** 测试 */
-    TEST("TEST");
-
-    private final String value;
-
-    DemoEnum(String value) {
-        this.value = value;
-    }
-}

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

@@ -1,25 +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.mapper;
-
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import vip.xiaonuo.biz.modular.demo.entity.Demo;
-
-/**
- * 例子Mapper接口
- *
- * @author 曹钊瑞
- * @date  2024/06/28 17:57
- **/
-public interface DemoMapper extends BaseMapper<Demo> {
-}

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

@@ -1,5 +0,0 @@
-<?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>

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

@@ -1,53 +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.param;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Getter;
-import lombok.Setter;
-
-import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.NotNull;
-import java.math.BigDecimal;
-import java.util.Date;
-
-/**
- * 例子添加参数
- *
- * @author 曹钊瑞
- * @date  2024/06/28 17:57
- **/
-@Getter
-@Setter
-public class DemoAddParam {
-
-    /** NAME */
-    @Schema(description = "NAME", requiredMode = Schema.RequiredMode.REQUIRED)
-    @NotBlank(message = "name不能为空")
-    private String name;
-
-    /** AGE */
-    @Schema(description = "AGE", requiredMode = Schema.RequiredMode.REQUIRED)
-    @NotBlank(message = "age不能为空")
-    private String age;
-
-    /** SEX */
-    @Schema(description = "SEX", requiredMode = Schema.RequiredMode.REQUIRED)
-    @NotBlank(message = "sex不能为空")
-    private String sex;
-
-    /** REMARK */
-    @Schema(description = "REMARK")
-    private String remark;
-
-}

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

@@ -1,58 +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.param;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Getter;
-import lombok.Setter;
-
-import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.NotNull;
-import java.math.BigDecimal;
-import java.util.Date;
-
-/**
- * 例子编辑参数
- *
- * @author 曹钊瑞
- * @date  2024/06/28 17:57
- **/
-@Getter
-@Setter
-public class DemoEditParam {
-
-    /** ID */
-    @Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED)
-    @NotBlank(message = "id不能为空")
-    private String id;
-
-    /** NAME */
-    @Schema(description = "NAME", requiredMode = Schema.RequiredMode.REQUIRED)
-    @NotBlank(message = "name不能为空")
-    private String name;
-
-    /** AGE */
-    @Schema(description = "AGE", requiredMode = Schema.RequiredMode.REQUIRED)
-    @NotBlank(message = "age不能为空")
-    private String age;
-
-    /** SEX */
-    @Schema(description = "SEX", requiredMode = Schema.RequiredMode.REQUIRED)
-    @NotBlank(message = "sex不能为空")
-    private String sex;
-
-    /** REMARK */
-    @Schema(description = "REMARK")
-    private String remark;
-
-}

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

@@ -1,35 +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.param;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Getter;
-import lombok.Setter;
-
-import jakarta.validation.constraints.NotBlank;
-
-/**
- * 例子Id参数
- *
- * @author 曹钊瑞
- * @date  2024/06/28 17:57
- **/
-@Getter
-@Setter
-public class DemoIdParam {
-
-    /** ID */
-    @Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED)
-    @NotBlank(message = "id不能为空")
-    private String id;
-}

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

@@ -1,63 +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.param;
-
-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/06/28 17:57
- **/
-@Getter
-@Setter
-public class DemoPageParam {
-
-    /** 当前页 */
-    @Schema(description = "当前页码")
-    private Integer current;
-
-    /** 每页条数 */
-    @Schema(description = "每页条数")
-    private Integer size;
-
-    /** 排序字段 */
-    @Schema(description = "排序字段,字段驼峰名称,如:userName")
-    private String sortField;
-
-    /** 排序方式 */
-    @Schema(description = "排序方式,升序:ASCEND;降序:DESCEND")
-    private String sortOrder;
-
-    /** 关键词 */
-    @Schema(description = "关键词")
-    private String searchKey;
-
-    /** NAME */
-    @Schema(description = "NAME")
-    private String name;
-
-    /** AGE */
-    @Schema(description = "AGE")
-    private String age;
-
-    /** SEX */
-    @Schema(description = "SEX")
-    private String sex;
-
-}

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

@@ -1,80 +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;
-
-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 java.util.List;
-
-/**
- * 例子Service接口
- *
- * @author 曹钊瑞
- * @date  2024/06/28 17:57
- **/
-public interface DemoService extends IService<Demo> {
-
-    /**
-     * 获取例子分页
-     *
-     * @author 曹钊瑞
-     * @date  2024/06/28 17:57
-     */
-    Page<Demo> page(DemoPageParam demoPageParam);
-
-    /**
-     * 添加例子
-     *
-     * @author 曹钊瑞
-     * @date  2024/06/28 17:57
-     */
-    void add(DemoAddParam demoAddParam);
-
-    /**
-     * 编辑例子
-     *
-     * @author 曹钊瑞
-     * @date  2024/06/28 17:57
-     */
-    void edit(DemoEditParam demoEditParam);
-
-    /**
-     * 删除例子
-     *
-     * @author 曹钊瑞
-     * @date  2024/06/28 17:57
-     */
-    void delete(List<DemoIdParam> demoIdParamList);
-
-    /**
-     * 获取例子详情
-     *
-     * @author 曹钊瑞
-     * @date  2024/06/28 17:57
-     */
-    Demo detail(DemoIdParam demoIdParam);
-
-    /**
-     * 获取例子详情
-     *
-     * @author 曹钊瑞
-     * @date  2024/06/28 17:57
-     **/
-    Demo queryEntity(String id);
-}

+ 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/06/28 17:57
- **/
-@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;
-    }
-}

+ 4 - 0
snowy-plugin/snowy-plugin-gen/src/main/java/vip/xiaonuo/gen/modular/basic/entity/GenBasic.java

@@ -103,4 +103,8 @@ public class GenBasic extends CommonEntity {
     /** 作者 */
     @Schema(description = "作者")
     private String authorName;
+
+    /** 表单模式 */
+    @Schema(description = "表单模式")
+    private String formMode;
 }

+ 16 - 2
snowy-plugin/snowy-plugin-gen/src/main/java/vip/xiaonuo/gen/modular/basic/service/impl/GenBasicServiceImpl.java

@@ -98,8 +98,12 @@ public class GenBasicServiceImpl extends ServiceImpl<GenBasicMapper, GenBasic> i
 
     private static final List<JSONObject> GEN_FRONT_FILE_LIST = CollectionUtil.newArrayList(
             JSONUtil.createObj().set("name", "Api.js.btl").set("path", "api"),
+            // formMode:dialog
             JSONUtil.createObj().set("name", "form.vue.btl").set("path",  "views"),
-            JSONUtil.createObj().set("name", "index.vue.btl").set("path",  "views"));
+            JSONUtil.createObj().set("name", "index.vue.btl").set("path",  "views"),
+            // formMode:inside
+            JSONUtil.createObj().set("name", "detail.vue.btl").set("path",  "views"),
+            JSONUtil.createObj().set("name", "index_inside.vue.btl").set("path",  "views"));
 
     private static final List<JSONObject> GEN_MOBILE_FILE_LIST = CollectionUtil.newArrayList(
             JSONUtil.createObj().set("name", "page.json.btl"),
@@ -515,11 +519,21 @@ public class GenBasicServiceImpl extends ServiceImpl<GenBasicMapper, GenBasic> i
                     genBasicCodeFrontResult.setCodeFileName(resultName);
                     genBasicCodeFrontResult.setCodeFileWithPathName(genFrontBasicPath + fileTemplatePath + File.separator + resultName);
                 } else {
+                    if ("index_inside.vue".equalsIgnoreCase(resultName)) {
+                        resultName = "index.vue";
+                    }
                     genBasicCodeFrontResult.setCodeFileName(resultName);
                     genBasicCodeFrontResult.setCodeFileWithPathName(genFrontBasicPath + fileTemplatePath + File.separator + genBasic.getBusName() + File.separator + resultName);
                 }
                 genBasicCodeFrontResult.setCodeFileContent(templateFront.render());
-                genBasicCodeFrontendResultList.add(genBasicCodeFrontResult);
+                if (!(
+                    "dialog".equals(genBasic.getFormMode()) && "index_inside.vue.btl".equalsIgnoreCase(fileTemplateName) ||
+                    "dialog".equals(genBasic.getFormMode()) && "detail.vue.btl".equalsIgnoreCase(fileTemplateName) ||
+                    "inside".equals(genBasic.getFormMode()) && "index.vue.btl".equalsIgnoreCase(fileTemplateName) ||
+                    "inside".equals(genBasic.getFormMode()) && "form.vue.btl".equalsIgnoreCase(fileTemplateName)
+                )) {
+                    genBasicCodeFrontendResultList.add(genBasicCodeFrontResult);
+                }
             });
             genBasicPreviewResult.setGenBasicCodeFrontendResultList(genBasicCodeFrontendResultList);
 

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

@@ -0,0 +1,184 @@
+<template>
+    <a-card :bordered="false">
+		<a-page-header
+			:title="formData.${configList[i].fieldNameCamelCase} ? '编辑${functionName}' : '增加${functionName}'"
+			@back="onClose"
+		>
+			<template #extra>
+				<a-button style="margin-right: 8px" @click="onClose">关闭</a-button>
+				<a-button type="primary" @click="onSubmit" :loading="submitLoading">保存</a-button>
+			</template>
+		</a-page-header>
+		<a-form ref="formRef" :model="formData" :rules="formRules" layout="${formLayout}">
+        		<% if(gridWhether) { %>
+        			<a-row :gutter="16">
+        			<% for(var i = 0; i < configList.~size; i++) { %>
+        			<% if(!configList[i].needTableId && configList[i].whetherAddUpdate) { %>
+        				<a-col :span="12">
+        					<a-form-item label="${configList[i].fieldRemark}:" name="${configList[i].fieldNameCamelCase}">
+        						<% if(configList[i].effectType == 'input') { %>
+        						<a-input v-model:value="formData.${configList[i].fieldNameCamelCase}" placeholder="请输入${configList[i].fieldRemark}" allow-clear />
+        						<% } else if (configList[i].effectType == 'textarea') {%>
+        						<a-textarea v-model:value="formData.${configList[i].fieldNameCamelCase}" placeholder="请输入${configList[i].fieldRemark}" :auto-size="{ minRows: 3, maxRows: 5 }" />
+        						<% } else if (configList[i].effectType == 'select') {%>
+        						<a-select v-model:value="formData.${configList[i].fieldNameCamelCase}" placeholder="请选择${configList[i].fieldRemark}" :options="${configList[i].fieldNameCamelCase}Options" />
+        						<% } else if (configList[i].effectType == 'radio') {%>
+        						<a-radio-group v-model:value="formData.${configList[i].fieldNameCamelCase}" placeholder="请选择${configList[i].fieldRemark}" :options="${configList[i].fieldNameCamelCase}Options" />
+        						<% } else if (configList[i].effectType == 'checkbox') {%>
+        						<a-checkbox-group v-model:value="formData.${configList[i].fieldNameCamelCase}" placeholder="请选择${configList[i].fieldRemark}" :options="${configList[i].fieldNameCamelCase}Options" />
+        						<% } else if (configList[i].effectType == 'datepicker') {%>
+        						<a-date-picker v-model:value="formData.${configList[i].fieldNameCamelCase}" value-format="YYYY-MM-DD HH:mm:ss" show-time placeholder="请选择${configList[i].fieldRemark}" style="width: 100%" />
+        						<% } else if (configList[i].effectType == 'timepicker') {%>
+        						<a-time-picker v-model:value="formData.${configList[i].fieldNameCamelCase}" placeholder="请选择${configList[i].fieldRemark}" style="width: 100%" />
+        						<% } else if (configList[i].effectType == 'inputNumber') {%>
+        						<a-input-number v-model:value="formData.${configList[i].fieldNameCamelCase}" :min="1" :max="10000" style="width: 100%" />
+        						<% } else if (configList[i].effectType == 'slider') {%>
+        						<a-slider v-model:value="formData.${configList[i].fieldNameCamelCase}" :max="1000" style="width: 100%" />
+        						<% } else if (configList[i].effectType == 'fileUpload') {%>
+        						<xn-upload v-model:value="formData.${configList[i].fieldNameCamelCase}" />
+        						<% } else if (configList[i].effectType == 'imageUpload') {%>
+        						<xn-upload v-model:value="formData.${configList[i].fieldNameCamelCase}" uploadMode="image" />
+        						<% } else if (configList[i].effectType == 'editor') {%>
+        						<xn-editor v-model:value="formData.${configList[i].fieldNameCamelCase}" placeholder="请输入${configList[i].fieldRemark}" />
+        						<% } %>
+        					</a-form-item>
+        				</a-col>
+        			<% } %>
+        			<% } %>
+        			</a-row>
+        		<% } else { %>
+        		<% for(var i = 0; i < configList.~size; i++) { %>
+        		<% if(!configList[i].needTableId && configList[i].whetherAddUpdate) { %>
+        			<a-form-item label="${configList[i].fieldRemark}:" name="${configList[i].fieldNameCamelCase}">
+        				<% if(configList[i].effectType == 'input') { %>
+        				<a-input v-model:value="formData.${configList[i].fieldNameCamelCase}" placeholder="请输入${configList[i].fieldRemark}" allow-clear />
+        				<% } else if (configList[i].effectType == 'textarea') {%>
+        				<a-textarea v-model:value="formData.${configList[i].fieldNameCamelCase}" placeholder="请输入${configList[i].fieldRemark}" :auto-size="{ minRows: 3, maxRows: 5 }" />
+        				<% } else if (configList[i].effectType == 'select') {%>
+        				<a-select v-model:value="formData.${configList[i].fieldNameCamelCase}" placeholder="请选择${configList[i].fieldRemark}" :options="${configList[i].fieldNameCamelCase}Options" />
+        				<% } else if (configList[i].effectType == 'radio') {%>
+        				<a-radio-group v-model:value="formData.${configList[i].fieldNameCamelCase}" placeholder="请选择${configList[i].fieldRemark}" :options="${configList[i].fieldNameCamelCase}Options" />
+        				<% } else if (configList[i].effectType == 'checkbox') {%>
+        				<a-checkbox-group v-model:value="formData.${configList[i].fieldNameCamelCase}" placeholder="请选择${configList[i].fieldRemark}" :options="${configList[i].fieldNameCamelCase}Options" />
+        				<% } else if (configList[i].effectType == 'datepicker') {%>
+        				<a-date-picker v-model:value="formData.${configList[i].fieldNameCamelCase}" value-format="YYYY-MM-DD HH:mm:ss" show-time placeholder="请选择${configList[i].fieldRemark}" style="width: 100%" />
+        				<% } else if (configList[i].effectType == 'timepicker') {%>
+        				<a-time-picker v-model:value="formData.${configList[i].fieldNameCamelCase}" value-format="YYYY-MM-DD HH:mm:ss" show-time placeholder="请选择${configList[i].fieldRemark}" style="width: 100%" />
+        				<% } else if (configList[i].effectType == 'inputNumber') {%>
+        				<a-input-number v-model:value="formData.${configList[i].fieldNameCamelCase}" placeholder="请输入${configList[i].fieldRemark}" :min="1" :max="10000" style="width: 100%" />
+        				<% } else if (configList[i].effectType == 'slider') {%>
+        				<a-slider v-model:value="formData.${configList[i].fieldNameCamelCase}" placeholder="请滑动${configList[i].fieldRemark}" :max="1000" style="width: 100%" />
+        				<% } else if (configList[i].effectType == 'fileUpload') {%>
+        				<xn-upload v-model:value="formData.${configList[i].fieldNameCamelCase}" />
+        				<% } else if (configList[i].effectType == 'imageUpload') {%>
+        				<xn-upload v-model:value="formData.${configList[i].fieldNameCamelCase}" uploadMode="image" />
+        				<% } else if (configList[i].effectType == 'editor') {%>
+        				<xn-editor v-model:value="formData.${configList[i].fieldNameCamelCase}" placeholder="请输入${configList[i].fieldRemark}" />
+        				<% } %>
+        			</a-form-item>
+        		<% } %>
+        		<% } %>
+        		<% } %>
+        		</a-form>
+	</a-card>
+</template>
+
+<script setup name="${classNameFirstLower}Detail">
+	<%
+	var iptTool = 0;
+	for(var i = 0; i < configList.~size; i++) {
+		if(!configList[i].needTableId) {
+		if(configList[i].effectType == 'select' || configList[i].effectType == 'radio' || configList[i].effectType == 'checkbox') {
+			iptTool++;
+		}
+		}
+	}
+	%>
+	<% if(iptTool > 0) { %>
+	import tool from '@/utils/tool'
+	<% } %>
+	import { cloneDeep } from 'lodash-es'
+	import { required } from '@/utils/formRules'
+	import ${classNameFirstLower}Api from '@/api/${moduleName}/${classNameFirstLower}Api'
+	// 抽屉状态
+	const emit = defineEmits({ successful: null })
+	const formRef = ref()
+	// 表单数据
+	const formData = ref({})
+	const submitLoading = ref(false)
+	<% for(var i = 0; i < configList.~size; i++) { %>
+	<% if(!configList[i].needTableId) { %>
+	<% if(configList[i].effectType == 'select' || configList[i].effectType == 'radio' || configList[i].effectType == 'checkbox') { %>
+	const ${configList[i].fieldNameCamelCase}Options = ref([])
+	<% } %>
+	<% } %>
+	<% } %>
+
+	// 打开抽屉
+	const onOpen = (record) => {
+		if (record) {
+			let recordData = cloneDeep(record)
+			<% for(var i = 0; i < configList.~size; i++) { %>
+			<% if(!configList[i].needTableId && configList[i].whetherAddUpdate && configList[i].effectType == 'checkbox') { %>
+			recordData.${configList[i].fieldNameCamelCase} = JSON.parse(recordData.${configList[i].fieldNameCamelCase})
+			<% } %>
+			<% } %>
+			formData.value = Object.assign({}, recordData)
+		}
+		<% for(var i = 0; i < configList.~size; i++) { %>
+		<% if(!configList[i].needTableId) { %>
+		<% if(configList[i].effectType == 'select' || configList[i].effectType == 'radio' || configList[i].effectType == 'checkbox') { %>
+		${configList[i].fieldNameCamelCase}Options.value = tool.dictList('${configList[i].dictTypeCode}')
+		<% } %>
+		<% } %>
+		<% } %>
+	}
+	// 关闭抽屉
+	const onClose = () => {
+		formRef.value.resetFields()
+		formData.value = {}
+		emit('onClose')
+	}
+	// 默认要校验的
+	const formRules = {
+		<% for(var i = 0; i < configList.~size; i++) { %>
+		<% if(!configList[i].needTableId) { %>
+		<% if(configList[i].required) { %>
+		${configList[i].fieldNameCamelCase}: [required('请输入${configList[i].fieldRemark}')],
+		<% } %>
+		<% } %>
+		<% } %>
+	}
+	// 验证并提交数据
+	const onSubmit = () => {
+		formRef.value
+			.validate()
+			.then(() => {
+				submitLoading.value = true
+				const formDataParam = cloneDeep(formData.value)
+				<% for(var i = 0; i < configList.~size; i++) { %>
+				<% if(configList[i].whetherAddUpdate && configList[i].effectType == 'checkbox') { %>
+				formDataParam.${configList[i].fieldNameCamelCase} = JSON.stringify(formDataParam.${configList[i].fieldNameCamelCase})
+				<% } %>
+				<% } %>
+				${classNameFirstLower}Api
+					<% for(var i = 0; i < configList.~size; i++) { %>
+					<% if(configList[i].needTableId) { %>
+					.${classNameFirstLower}SubmitForm(formDataParam, formDataParam.${configList[i].fieldNameCamelCase})
+					<% } %>
+					<% } %>
+					.then(() => {
+						onClose()
+						emit('successful')
+					})
+					.finally(() => {
+						submitLoading.value = false
+					})
+			})
+			.catch(() => {})
+	}
+	// 抛出函数
+	defineExpose({
+		onOpen
+	})
+</script>

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

@@ -0,0 +1,281 @@
+<template>
+	<%
+	var searchCount = 0;
+	var row = 0;
+	%>
+	<% for(var i = 0; i < configList.~size; i++) { %>
+		<% if(!configList[i].needTableId && configList[i].needPage) { searchCount ++; }%>
+	<% } %>
+	<a-card :bordered="false" v-if="indexShow">
+		<% if (searchCount > 0) { %>
+		<a-form ref="searchFormRef" name="advanced_search" :model="searchFormState" class="ant-advanced-search-form">
+			<a-row :gutter="24">
+				<% for(var i = 0; i < configList.~size; i++) { %>
+				<% if(!configList[i].needTableId && configList[i].needPage) { row ++; %>
+				<% if(row <= 3) { %>
+				<a-col :span="6">
+				<% if(configList[i].effectType == 'input' || configList[i].effectType == 'textarea') { %>
+					<a-form-item label="${configList[i].fieldRemark}" name="${configList[i].fieldNameCamelCase}">
+						<a-input v-model:value="searchFormState.${configList[i].fieldNameCamelCase}" placeholder="请输入${configList[i].fieldRemark}" />
+					</a-form-item>
+				<% } else if (configList[i].effectType == 'select' || configList[i].effectType == 'radio' || configList[i].effectType == 'checkbox') {%>
+					<a-form-item label="${configList[i].fieldRemark}" name="${configList[i].fieldNameCamelCase}">
+						<a-select v-model:value="searchFormState.${configList[i].fieldNameCamelCase}" placeholder="请选择${configList[i].fieldRemark}" :options="${configList[i].fieldNameCamelCase}Options" />
+					</a-form-item>
+				<% } else if (configList[i].effectType == 'inputNumber' || configList[i].effectType == 'slider') {%>
+					<a-form-item label="${configList[i].fieldRemark}" name="${configList[i].fieldNameCamelCase}">
+						<a-input-number v-model:value="searchFormState.${configList[i].fieldNameCamelCase}" placeholder="请输入${configList[i].fieldRemark}" style="width: 100%" />
+					</a-form-item>
+				<% } else if (configList[i].effectType == 'datepicker') {%>
+					<a-form-item label="${configList[i].fieldRemark}" name="${configList[i].fieldNameCamelCase}">
+						<a-range-picker v-model:value="searchFormState.${configList[i].fieldNameCamelCase}" value-format="YYYY-MM-DD HH:mm:ss" show-time />
+					</a-form-item>
+				<% } else {%>
+					<a-form-item label="${configList[i].fieldRemark}" name="${configList[i].fieldNameCamelCase}">
+						<a-input v-model:value="searchFormState.${configList[i].fieldNameCamelCase}" placeholder="请输入${configList[i].fieldRemark}" />
+					</a-form-item>
+				<% } %>
+				</a-col>
+				<% } else { %>
+				<a-col :span="6" v-show="advanced">
+				<% if(configList[i].effectType == 'input' || configList[i].effectType == 'textarea') { %>
+					<a-form-item label="${configList[i].fieldRemark}" name="${configList[i].fieldNameCamelCase}">
+						<a-input v-model:value="searchFormState.${configList[i].fieldNameCamelCase}" placeholder="请输入${configList[i].fieldRemark}" />
+					</a-form-item>
+				<% } else if (configList[i].effectType == 'select' || configList[i].effectType == 'radio' || configList[i].effectType == 'checkbox') {%>
+					<a-form-item label="${configList[i].fieldRemark}" name="${configList[i].fieldNameCamelCase}">
+						<a-select v-model:value="searchFormState.${configList[i].fieldNameCamelCase}" placeholder="请选择${configList[i].fieldRemark}" :options="${configList[i].fieldNameCamelCase}Options" />
+					</a-form-item>
+				<% } else if (configList[i].effectType == 'inputNumber' || configList[i].effectType == 'slider') {%>
+					<a-form-item label="${configList[i].fieldRemark}" name="${configList[i].fieldNameCamelCase}">
+						<a-input-number v-model:value="searchFormState.${configList[i].fieldNameCamelCase}" placeholder="请输入${configList[i].fieldRemark}" style="width: 100%" />
+					</a-form-item>
+				<% } else if (configList[i].effectType == 'datepicker') {%>
+					<a-form-item label="${configList[i].fieldRemark}" name="${configList[i].fieldNameCamelCase}">
+						<a-range-picker v-model:value="searchFormState.${configList[i].fieldNameCamelCase}" show-time />
+					</a-form-item>
+				<% } else {%>
+					<a-form-item label="${configList[i].fieldRemark}" name="${configList[i].fieldNameCamelCase}">
+						<a-input v-model:value="searchFormState.${configList[i].fieldNameCamelCase}" placeholder="请输入${configList[i].fieldRemark}" />
+					</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>
+					<% if(searchCount > 3) { %>
+					<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
+			<% for(var i = 0; i < configList.~size; i++) { %>
+			<% if(configList[i].needTableId) { %>
+			:row-key="(record) => record.${configList[i].fieldNameCamelCase}"
+			<% } %>
+			<% } %>
+			:tool-config="toolConfig"
+			:row-selection="options.rowSelection"
+		>
+			<template #operator class="table-operator">
+				<a-space>
+					<a-button type="primary" @click="onDetail()" v-if="hasPerm('${classNameFirstLower}Add')">
+						<template #icon><plus-outlined /></template>
+						新增
+					</a-button>
+					<xn-batch-delete
+						v-if="hasPerm('${classNameFirstLower}BatchDelete')"
+						:selectedRowKeys="selectedRowKeys"
+						@batchDelete="deleteBatch${className}"
+					/>
+				</a-space>
+			</template>
+			<template #bodyCell="{ column, record }">
+				<% for(var i = 0; i < configList.~size; i++) { %>
+				<% if(!configList[i].needTableId && configList[i].whetherTable) { %>
+				<% if (configList[i].effectType == 'select' || configList[i].effectType == 'radio') { %>
+				<template v-if="column.dataIndex === '${configList[i].fieldNameCamelCase}'">
+					{{ $TOOL.dictTypeData('${configList[i].dictTypeCode}', record.${configList[i].fieldNameCamelCase}) }}
+				</template>
+				<% } else if (configList[i].effectType == 'checkbox') { %>
+				<template v-if="column.dataIndex === '${configList[i].fieldNameCamelCase}'">
+					<a-tag v-for="textValue in JSON.parse(record.${configList[i].fieldNameCamelCase})" :key="textValue" color="green">{{ $TOOL.dictTypeData('${configList[i].dictTypeCode}', textValue) }}</a-tag>
+				</template>
+				<% } else if (configList[i].effectType == 'imageUpload') { %>
+				<template v-if="column.dataIndex === '${configList[i].fieldNameCamelCase}'">
+					<a-image :src="record.${configList[i].fieldNameCamelCase}" style="width: 30px; height: 30px;" />
+				</template>
+				<% } else if (configList[i].effectType == 'fileUpload') { %>
+				<template v-if="column.dataIndex === '${configList[i].fieldNameCamelCase}'">
+					<a :href="record.${configList[i].fieldNameCamelCase}" :target="record.${configList[i].fieldNameCamelCase}">{{ record.${configList[i].fieldNameCamelCase} }}</a>
+				</template>
+				<% } %>
+				<% } %>
+				<% } %>
+				<template v-if="column.dataIndex === 'action'">
+					<a-space>
+						<a @click="onDetail(record)" v-if="hasPerm('${classNameFirstLower}Edit')">编辑</a>
+						<a-divider type="vertical" v-if="hasPerm(['${classNameFirstLower}Edit', '${classNameFirstLower}Delete'], 'and')" />
+						<a-popconfirm title="确定要删除吗?" @confirm="delete${className}(record)">
+							<a-button type="link" danger size="small" v-if="hasPerm('${classNameFirstLower}Delete')">删除</a-button>
+						</a-popconfirm>
+					</a-space>
+				</template>
+			</template>
+		</s-table>
+	</a-card>
+	<Detail v-else ref="detailRef" @onClose="indexShow = true" @successful="tableRef.refresh()" />
+</template>
+
+<script setup name="${busName}">
+	<%
+	var iptTool = 0;
+	if (searchCount > 0) {
+		for(var i = 0; i < configList.~size; i++) {
+			if(!configList[i].needTableId) {
+			if(configList[i].effectType == 'select' || configList[i].effectType == 'radio' || configList[i].effectType == 'checkbox') {
+				iptTool++;
+			}
+			}
+		}
+	}
+	%>
+	<% if(iptTool > 0) { %>
+	import tool from '@/utils/tool'
+	<% } %>
+	import { cloneDeep } from 'lodash-es'
+	import Detail from './detail.vue'
+	import ${classNameFirstLower}Api from '@/api/${moduleName}/${classNameFirstLower}Api'
+	<% if (searchCount > 0) { %>
+	const searchFormState = ref({})
+	const searchFormRef = ref()
+	<% } %>
+	const tableRef = ref()
+	const detailRef = ref()
+	const indexShow = ref(true)
+	const toolConfig = { refresh: true, height: true, columnSetting: true, striped: false }
+	<% if(searchCount > 3) { %>
+	// 查询区域显示更多控制
+	const advanced = ref(false)
+	const toggleAdvanced = () => {
+		advanced.value = !advanced.value
+	}
+	<% } %>
+	const columns = [
+	<% for(var i = 0; i < configList.~size; i++) { %>
+	<% if(!configList[i].needTableId && configList[i].whetherTable) { %>
+		{
+			title: '${configList[i].fieldRemark}',
+			dataIndex: '${configList[i].fieldNameCamelCase}'<% if(configList[i].whetherRetract) { %>,<% } %>
+			<% if(configList[i].whetherRetract) { %>
+			ellipsis: true
+			<% } %>
+		},
+	<% } %>
+	<% } %>
+	]
+	// 操作栏通过权限判断是否显示
+	if (hasPerm(['${classNameFirstLower}Edit', '${classNameFirstLower}Delete'])) {
+		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) => {
+		<% if (searchCount > 0) { %>
+		const searchFormParam = cloneDeep(searchFormState.value)
+		<% for(var i = 0; i < configList.~size; i++) { %>
+		<% if(!configList[i].needTableId && configList[i].needPage) { %>
+		<% if (configList[i].effectType == 'datepicker') {%>
+		// ${configList[i].fieldNameCamelCase}范围查询条件重载
+		if (searchFormParam.${configList[i].fieldNameCamelCase}) {
+			searchFormParam.start${configList[i].fieldNameCamelCaseFirstUpper} = searchFormParam.${configList[i].fieldNameCamelCase}[0]
+			searchFormParam.end${configList[i].fieldNameCamelCaseFirstUpper} = searchFormParam.${configList[i].fieldNameCamelCase}[1]
+			delete searchFormParam.${configList[i].fieldNameCamelCase}
+		}
+		<% } %>
+		<% } %>
+		<% } %>
+		return ${classNameFirstLower}Api.${classNameFirstLower}Page(Object.assign(parameter, searchFormParam)).then((data) => {
+		<% } else { %>
+		return ${classNameFirstLower}Api.${classNameFirstLower}Page(parameter).then((data) => {
+		<% } %>
+			return data
+		})
+	}
+	// 重置
+	const reset = () => {
+		searchFormRef.value.resetFields()
+		tableRef.value.refresh(true)
+	}
+	// 删除
+	const delete${className} = (record) => {
+		let params = [
+			{
+				<% for(var i = 0; i < configList.~size; i++) { %>
+				<% if(configList[i].needTableId) { %>
+				${configList[i].fieldNameCamelCase}: record.${configList[i].fieldNameCamelCase}
+				<% } %>
+				<% } %>
+			}
+		]
+		${classNameFirstLower}Api.${classNameFirstLower}Delete(params).then(() => {
+			tableRef.value.refresh(true)
+		})
+	}
+	// 批量删除
+	const deleteBatch${className} = (params) => {
+		${classNameFirstLower}Api.${classNameFirstLower}Delete(params).then(() => {
+			tableRef.value.clearRefreshSelected()
+		})
+	}
+	// 切换至表单
+    const onDetail = (record = null) => {
+    	indexShow.value = false
+    	nextTick(() => {
+    		if (record) {
+    			detailRef.value.onOpen(record)
+    		}
+    	})
+    }
+	<% if (searchCount > 0) { %>
+	<% for(var i = 0; i < configList.~size; i++) { %>
+	<% if(!configList[i].needTableId && configList[i].needPage) { %>
+	<% if (configList[i].effectType == 'select' || configList[i].effectType == 'radio' || configList[i].effectType == 'checkbox') { %>
+	const ${configList[i].fieldNameCamelCase}Options = tool.dictList('${configList[i].dictTypeCode}')
+	<% } %>
+	<% } %>
+	<% } %>
+	<% } %>
+</script>