Browse Source

refactor(rules): 删除不再使用的模板规则文件,优化项目结构

PIGCLOUD 1 month ago
parent
commit
905687f854

+ 0 - 111
.cursor/rules/development-workflow.mdc

@@ -1,111 +0,0 @@
----
-description: 
-globs: 
-alwaysApply: false
----
-# Development Workflow
-
-## Using CGTM Templates
-
-### 1. Template Selection
-
-Choose the appropriate template group based on your needs:
-- **单表增删改查** - For simple CRUD operations on a single table
-- **主子表增删改查** - For parent-child relationships (e.g., Order-OrderItems)
-- **vform** - For visual form designer integration
-
-### 2. Configuration Setup
-
-Before generating code, ensure these variables are configured:
-
-**Basic Information:**
-- `author` - Developer name
-- `package` - Base package (e.g., com.pigx.app)
-- `moduleName` - Module identifier (e.g., system, business)
-- `functionName` - Feature name (e.g., user, product)
-
-**Database Configuration:**
-- `tableName` - Database table name
-- `tableComment` - Table description
-- `fieldList` - Field definitions from database
-
-**Path Configuration:**
-- `backendPath` - Backend project root path
-- `frontendPath` - Frontend project root path
-
-### 3. Code Generation Process
-
-1. **Analyze Database Schema**
-   - Primary keys are marked with `primaryPk = '1'`
-   - Auto-fill fields configured (INSERT, UPDATE, INSERT_UPDATE)
-   - Logical deletion field is `del_flag`
-
-2. **Generate Backend Code**
-   - Entity with proper annotations
-   - Mapper interface and XML
-   - Service interface and implementation
-   - Controller with REST endpoints
-
-3. **Generate Frontend Code**
-   - API client in TypeScript
-   - Table component for data display
-   - Form component for data entry
-   - i18n translations if needed
-
-4. **Generate SQL Scripts**
-   - Permission entries
-   - Menu configuration
-
-### 4. Post-Generation Tasks
-
-After code generation:
-
-1. **Review Generated Code**
-   - Check import statements
-   - Verify field mappings
-   - Ensure proper annotations
-
-2. **Customize Business Logic**
-   - Add validation rules
-   - Implement custom queries
-   - Add business-specific methods
-
-3. **Configure Permissions**
-   - Run generated SQL scripts
-   - Assign roles and permissions
-   - Test access control
-
-4. **Frontend Integration**
-   - Add routes
-   - Configure menu items
-   - Test CRUD operations
-
-### 5. Master-Detail Specifics
-
-For parent-child relationships:
-
-1. **Define Relationships**
-   - `mainField` - Parent table foreign key field
-   - `childField` - Child table reference field
-   - Configure cascade operations
-
-2. **Transaction Management**
-   - All operations wrapped in transactions
-   - Proper rollback on errors
-   - Batch operations for children
-
-3. **UI Considerations**
-   - Nested forms for data entry
-   - Inline editing for child records
-   - Proper validation across levels
-
-### 6. Best Practices
-
-- Always use logical deletion (`del_flag`) instead of physical deletion
-- Implement proper validation at both frontend and backend
-- Use dictionaries for standardized dropdowns
-- Follow RESTful conventions for APIs
-- Maintain consistent naming conventions
-- Add comprehensive API documentation with `@Schema` annotations
-- Use permission annotations for security
-- Implement audit logging with `@SysLog`

+ 0 - 100
.cursor/rules/java-templates.mdc

@@ -1,100 +0,0 @@
----
-description: 
-globs: 
-alwaysApply: false
----
-# Java Backend Template Patterns
-
-## Entity Template Pattern
-
-Entities follow the MyBatis-Plus active record pattern:
-
-```java
-@Data
-@TableName("${tableName}")
-@EqualsAndHashCode(callSuper = true)
-public class ${ClassName}Entity extends Model<${ClassName}Entity> {
-    // Fields with annotations
-}
-```
-
-Key annotations used:
-- `@TableId(type = IdType.ASSIGN_ID)` - For primary keys
-- `@TableField(fill = FieldFill.INSERT)` - Auto-fill on insert
-- `@TableLogic` - Logical deletion flag
-- `@Schema` - OpenAPI documentation
-
-## Controller Template Pattern
-
-Controllers follow RESTful conventions with Spring Boot:
-
-```java
-@RestController
-@RequiredArgsConstructor
-@RequestMapping("/${functionName}")
-@Tag(description = "${tableComment}", name = "${tableComment}管理")
-public class ${ClassName}Controller {
-    // CRUD endpoints
-}
-```
-
-Standard endpoints:
-- `GET /{id}` - Get by ID
-- `GET /page` - Paginated list
-- `POST` - Create new
-- `PUT` - Update existing
-- `DELETE` - Delete (logical or physical)
-
-## Service Layer Pattern
-
-Service interface:
-```java
-public interface ${ClassName}Service extends IService<${ClassName}Entity> {
-    // Custom business methods
-}
-```
-
-Implementation extends ServiceImpl:
-```java
-@Service
-@RequiredArgsConstructor
-public class ${ClassName}ServiceImpl extends ServiceImpl<${ClassName}Mapper, ${ClassName}Entity> 
-    implements ${ClassName}Service {
-    // Business logic implementation
-}
-```
-
-## Mapper Pattern
-
-MyBatis mapper interface:
-```java
-@Mapper
-public interface ${ClassName}Mapper extends BaseMapper<${ClassName}Entity> {
-    // Custom SQL methods
-}
-```
-
-## Multi-Tenant Support
-
-When `isTenant` is true:
-- Entity includes `@TenantTable` annotation
-- Automatic tenant filtering in queries
-- Tenant ID auto-fill on insert
-
-## Transaction Handling
-
-Master-detail operations use:
-```java
-@Transactional(rollbackFor = Exception.class)
-public Boolean save${ClassName}(${ClassName}Entity entity) {
-    // Parent save
-    // Children save/update/delete
-}
-```
-
-## Security Annotations
-
-Common security patterns:
-- `@PreAuthorize("@pms.hasPermission('${functionName}_add')")` - Permission check
-- `@SysLog("新增${tableComment}")` - Audit logging
-- `@Inner(false)` - Internal service access control

+ 0 - 52
.cursor/rules/project-overview.mdc

@@ -1,52 +0,0 @@
----
-description: 
-globs: 
-alwaysApply: true
----
-# CGTM Project Overview
-
-## What is CGTM?
-
-CGTM (Code Generation Template Market - 代码生成模板市场) is an online platform that provides various code generation templates to enhance developer experience. It's designed to work with the PIGX framework for rapid application development.
-
-## Project Purpose
-
-- Provide rich and diverse code generation templates
-- Enable easy template updates through "online update" functionality
-- Support community contributions via GitHub pull requests
-- Accelerate development workflow with pre-built templates
-
-## Core Technologies
-
-- **Template Engine**: Apache Velocity
-- **Backend**: Java with Spring Boot
-- **Frontend**: Vue.js with TypeScript
-- **Database Support**: Multiple database types through dynamic configuration
-- **Architecture**: Microservices with modular design
-
-## Template Categories
-
-1. **Single Table CRUD** (单表增删改查)
-   - Complete CRUD operations for single entities
-   - Includes Controller, Service, Mapper, Entity, and Vue components
-
-2. **Master-Detail CRUD** (主子表增删改查)
-   - Parent-child relationship management
-   - Complex form handling with nested data
-
-3. **VForm Templates**
-   - Visual form designer integration
-   - JSON-based form configuration
-
-## Key Features
-
-- Multi-tenant support (`isTenant` flag)
-- Internationalization (i18n) ready
-- Auto-fill fields support
-- Logical deletion support
-- Dynamic permission and menu generation
-- Modern UI with best UX practices
-
-## License
-
-AGPL 3.0 - Free for PIGX users only

+ 0 - 79
.cursor/rules/template-structure.mdc

@@ -1,79 +0,0 @@
----
-description: 
-globs: 
-alwaysApply: true
----
-# Template Structure Guide
-
-## Directory Organization
-
-```
-CGTM/
-├── single/              # Single table CRUD templates
-├── multiple/            # Master-detail table templates
-├── common/              # Shared templates across modules
-├── vform/               # Visual form designer templates
-└── config.json          # Template configuration mapping
-```
-
-## Template Configuration
-
-The [config.json](mdc:config.json) file defines template groups and their mappings:
-
-```json
-{
-  "单表增删改查": [...],     // Single table templates
-  "主子表增删改查": [...],   // Master-detail templates
-  "vform": [...]           // VForm templates
-}
-```
-
-Each template entry contains:
-- `templateName`: Display name of the template
-- `generatorPath`: Output path with variable substitution
-- `templateFile`: Source template file location
-
-## Single Table Templates
-
-Located in the [single/](mdc:single) directory:
-
-- [Controller.java](mdc:single/Controller.java) - REST API endpoints
-- [Service.java](mdc:single/Service.java) - Business logic interface
-- [ServiceImpl.java](mdc:single/ServiceImpl.java) - Service implementation
-- [实体.java](mdc:single/实体.java) - JPA/MyBatis entity
-- [Mapper.java](mdc:single/Mapper.java) - MyBatis mapper interface
-- [Mapper.xml](mdc:single/Mapper.xml) - SQL mappings
-- [表格.vue](mdc:single/表格.vue) - Data table component
-- [表单.vue](mdc:single/表单.vue) - Form component
-
-## Master-Detail Templates
-
-Located in the [multiple/](mdc:multiple) directory:
-
-- [主子Contoller.java](mdc:multiple/主子Contoller.java) - Parent-child REST APIs
-- [主子Service.java](mdc:multiple/主子Service.java) - Complex business logic
-- [主子ServiceImpl.java](mdc:multiple/主子ServiceImpl.java) - Implementation with transactions
-- [主实体.java](mdc:multiple/主实体.java) - Parent entity
-- [子实体.java](mdc:multiple/子实体.java) - Child entity
-- [子Mapper.java](mdc:multiple/子Mapper.java) - Child table mapper
-- [主子表格.vue](mdc:multiple/主子表格.vue) - Parent-child data display
-- [主子表单.vue](mdc:multiple/主子表单.vue) - Nested form handling
-
-## Common Templates
-
-Located in the [common/](mdc:common) directory:
-
-- [api.ts](mdc:common/api.ts) - TypeScript API client
-- [权限菜单.sql](mdc:common/权限菜单.sql) - Permission and menu SQL
-- [i18n中文模板.ts](mdc:common/i18n中文模板.ts) - Chinese translations
-- [i18n英文模板.ts](mdc:common/i18n英文模板.ts) - English translations
-
-## Path Variables
-
-Template paths support these variables:
-- `${backendPath}` - Backend project root
-- `${frontendPath}` - Frontend project root
-- `${packagePath}` - Java package path (com/example/app)
-- `${moduleName}` - Module name
-- `${ClassName}` - Entity class name
-- `${functionName}` - Function/feature name

+ 0 - 100
.cursor/rules/velocity.mdc

@@ -1,100 +0,0 @@
----
-description: 
-globs: 
-alwaysApply: true
----
-# Velocity Templates in CGTM
-
-This rule explains how Velocity templates are used for code generation in this project.
-
-## Basic Structure
-
-Velocity templates use a simple syntax with variables, directives, and references:
-- Variables start with `$` (e.g., `$ClassName`)
-- Directives start with `#` (e.g., `#foreach`, `#if`, `#end`)
-- Comments use `##`
-
-## Entity Template Example
-
-```java
-public class ${ClassName}Entity extends Model<${ClassName}Entity> {
-
-#foreach ($field in $fieldList)
-#if($field.primaryPk)
-    @TableId(type = IdType.ASSIGN_ID)
-#end
-    @Schema(description="$comment"#if($field.hidden),hidden=$field.hidden#end)
-    private $field.attrType $field.attrName;
-#end
-}
-```
-
-## Available Context Variables
-
-### Template Basic Properties
-| Variable | Description |
-|----------|-------------|
-| dbType | Database type |
-| package | Package name |
-| packagePath | Package path |
-| version | Version |
-| moduleName | Module name |
-| ModuleName | Module name (first letter capitalized) |
-| functionName | Function name |
-| FunctionName | Function name (first letter capitalized) |
-| formLayout | Form layout |
-| style | Style, corresponding template group |
-| author | Author |
-| datetime | Current date and time |
-| date | Current date |
-| importList | Import list |
-| tableName | Database table name |
-| tableComment | Database table comment |
-| className | Class name in lowercase |
-| ClassName | Class name |
-| fieldList | Field list |
-| backendPath | Backend path |
-| frontendPath | Frontend path |
-| childFieldList | Child table field list |
-| childTableName | Child table name |
-| mainField | Main table relation field name |
-| childField | Child table relation field name |
-| ChildClassName | Child class name (first letter capitalized) |
-| childClassName | Child class name in lowercase |
-| primaryList | Primary key field list |
-| formList | Form field list |
-| gridList | Grid field list |
-| queryList | Query field list |
-| pk | Primary key field |
-
-### Template Field Properties
-| Variable | Description |
-|----------|-------------|
-| dsName | Data source name |
-| tableName | Table name |
-| fieldName | SQL field name |
-| fieldType | SQL field type |
-| attrName | Java attribute name |
-| attrType | Java attribute type |
-| fieldComment | Field description |
-| sort | Sort |
-| packageName | Attribute package name |
-| autoFill | Auto fill |
-| primaryPk | Whether it's a primary key |
-| baseField | Whether it's a base class field |
-| formItem | Whether it's a form item |
-| formRequired | Form required |
-| formType | Form type |
-| formValidator | Form validator |
-| gridItem | Whether it's a list item |
-| gridSort | List sorting |
-| queryItem | Whether it's a query item |
-| queryType | Query method |
-| queryFormType | Query form type |
-| fieldDict | Field dictionary type |
-
-### Environment Variables
-| Variable | Description |
-|----------|-------------|
-| isSpringBoot3 | Whether it's SpringBoot 3 |
-| isTenant | Whether multi-tenant is supported |

File diff suppressed because it is too large
+ 8 - 4
CLAUDE.md


+ 1 - 1
VERSION

@@ -1 +1 @@
-V2025001
+V2026001

+ 0 - 108
common/vform.json

@@ -1,108 +0,0 @@
-#set($key=${dateTool.getSystemTime()})
-{
-  "widgetList": [
-    {
-      "key": $key,
-      "type": "grid",
-      "category": "container",
-      "icon": "grid",
-      "cols": [
-#foreach($field in $formList)
-#if($field.attrName != ${pk.attrName})
-        {
-          "type": "grid-col",
-          "category": "container",
-          "icon": "grid-col",
-          "internal": true,
-          "widgetList": [
-            {
-              "key": ${math.add($key,${foreach.index})},
-	#if($field.formType == 'text')
-              "type": "input",
-              "icon": "text-field",
-	#elseif($field.formType == 'number')
-              "type": "number",
-              "icon": "number-field",
-	#elseif($field.formType == 'textarea')
-              "type": "textarea",
-              "icon": "textarea-field",
-	#elseif($field.formType == 'select' && ${field.fieldDict})
-              "type": "select",
-              "icon": "select-field",
-	#elseif($field.formType == 'radio' && ${field.fieldDict})
-              "type": "radio",
-              "icon": "radio-field",
-	#elseif($field.formType == 'checkbox'  && ${field.fieldDict} )
-              "type": "checkbox",
-              "icon": "checkbox-field",
-	#elseif($field.formType == 'date')
-              "type": "date",
-              "icon": "date-field",
-	#elseif($field.formType == 'datetime')
-              "type": "time",
-              "icon": "time-field",
-	#elseif($field.formType == 'upload-file')
-              "type": "file-upload",
-              "icon": "file-upload-field",
-	#elseif($field.formType == 'upload-img')
-              "type": "picture-upload",
-              "icon": "picture-upload-field",
-	#elseif($field.formType == 'editor')
-              "type": "rich-editor",
-              "icon": "rich-editor-field",
-	#else
-              "type": "input",
-              "icon": "text-field",
-	#end
-              "formItemFlag": true,
-              "options": {
-	                "name": "${field.attrName}",
-	                "label": "#if(${field.fieldComment})${field.fieldComment}#else ${field.attrName}#end",
-	#if(($field.formType == 'select' || $field.formType == 'radio' || $field.formType == 'checkbox') && ${field.fieldDict})
-                    "optionItemsDictType": "${field.fieldDict}",
-	#end
-                    "placeholder": "请输入#if(${field.fieldComment})${field.fieldComment}#else ${field.attrName}#end"
-              },
-    #if($field.formRequired)
-             "required": true,
-    #end
-              "id": "input${math.add($key,${foreach.index})}"
-            }
-          ],
-          "options": {
-            "name": "gridCol${math.add($key,${foreach.index})}",
-            "hidden": false,
-            "offset": 0,
-            "push": 0,
-            "pull": 0,
-	#if($formLayout == 1)
-            "span": 24,
-	#elseif($formLayout == 2)
-            "span": 12,
-	#end
-            "responsive": false
-          },
-          "id": "grid-col-${math.add($key,${foreach.index})}"
-        }#if($foreach.hasNext),#end
-#end
-#end
-      ],
-      "options": {
-        "name": "grid${functionName}",
-        "hidden": false,
-        "gutter": 12
-      },
-      "id": "grid${functionName}"
-    }
-  ],
-  "formConfig": {
-    "modelName": "form",
-    "refName": "form",
-    "rulesName": "rules",
-    "labelWidth": 80,
-    "labelPosition": "left",
-    "labelAlign": "label-left-align",
-    "layoutType": "PC",
-    "jsonVersion": 3
-  }
-}

+ 0 - 218
common/vform.vue

@@ -1,218 +0,0 @@
-<template>
-    <el-dialog :title="form.${pk.attrName} ? '编辑' : '新增'" v-model="visible" :close-on-click-modal="false" draggable>
-      <el-form ref="dataFormRef" :model="form" :rules="dataRules" formDialogRef label-width="90px">
-#foreach($key in $resultMap.keySet())
-#set($itemList = $resultMap.get($key))
-<el-row :gutter="24">
-#foreach($field in $itemList)
-  <el-col :span="$field.span">
-#if($field.type == 'input')
-        <el-form-item label="${field.options.label}" prop="${field.options.name}">
-          <el-input v-model="form.${field.options.name}" placeholder="${field.options.placeholder}"/>
-        </el-form-item>
-#elseif($field.type == 'number')
-        <el-form-item label="${field.options.label}" prop="${field.options.name}">
-          <el-input-number :min="${field.options.min}" :max="${field.options.max}" v-model="form.${field.options.name}" placeholder="${field.options.placeholder}"></el-input-number>
-        </el-form-item>
-#elseif($field.type == 'textarea')
-        <el-form-item label="${field.options.label}" prop="${field.options.name}">
-          <el-input type="textarea" :rows="${field.options.rows}" v-model="form.${field.options.name}" placeholder="${field.options.placeholder}"/>
-        </el-form-item>
-#elseif($field.type == 'select')
-        <el-form-item label="${field.options.label}" prop="${field.options.name}">
-            <el-select v-model="form.${field.options.name}" placeholder="${field.options.placeholder}">
-       #if($field.options.optionItemsDictType)
-                <el-option :value="item.value" :label="item.label" v-for="(item, index) in ${field.options.optionItemsDictType}" :key="index"></el-option>
-       #else
-                <el-option label="请选择">0</el-option>
-       #end
-            </el-select>
-        </el-form-item>
-#elseif($field.type == 'radio')
-        <el-form-item label="${field.options.label}" prop="${field.options.name}">
-            <el-radio-group v-model="form.${field.options.name}">
-       #if($field.options.optionItemsDictType)
-             <el-radio :label="item.value" v-for="(item, index) in ${field.options.optionItemsDictType}" border :key="index">{{ item.label }}
-              </el-radio>
-       #end
-            </el-radio-group>
-        </el-form-item>
-#elseif($field.type == 'checkbox')
-        <el-form-item label="${field.options.label}" prop="${field.options.name}">
-            <el-checkbox-group v-model="form.${field.options.name}">
-       #if($field.options.optionItemsDictType)
-                <el-checkbox :label="item.value" :name="item.label" v-for="(item, index) in ${field.options.optionItemsDictType}" :key="index"></el-checkbox>
-       #else
-                <el-checkbox label="启用" name="type"></el-checkbox>
-                <el-checkbox label="禁用" name="type"></el-checkbox>
-       #end
-            </<el-checkbox-group>
-        </el-form-item>
-#elseif($field.type == 'date')
-        <el-form-item label="${field.options.label}" prop="${field.options.name}">
-            <el-date-picker type="date" placeholder="${field.options.placeholder}" v-model="form.${field.options.name}" :value-format="dateStr"></el-date-picker>
-        </el-form-item>
-#elseif($field.type == 'time')
-        <el-form-item label="${field.options.label}" prop="${field.options.name}">
-            <el-time-picker placeholder="${field.options.placeholder}" v-model="form.${field.options.name}" :value-format="dateTimeStr"></el-date-picker>
-        </el-form-item>
-#elseif($field.type == 'file-upload')
-        <el-form-item label="${field.options.label}" prop="${field.options.name}">
-            <upload-file  v-model="form.${field.attrName}" limit="${field.options.limit}" fileMaxSize="${field.options.fileMaxSize}"></upload-file>
-        </el-form-item>
-#elseif($field.type == 'picture-upload')
-        <el-form-item label="${field.options.label}" prop="${field.options.name}">
-            <upload-img v-model:imageUrl="form.${field.options.name}" limit="${field.options.limit}" fileMaxSize="${field.options.fileMaxSize}"></upload-img>
-        </el-form-item>
-#elseif($field.type == 'rich-editor')
-          <el-form-item label="${field.options.label}" prop="${field.options.name}">
-            <editor v-model:get-html="form.${field.options.name}" placeholder="${field.options.placeholder}"></editor>
-          </el-form-item>
-#elseif($field.type == 'switch')
-          <el-form-item label="${field.options.label}" prop="${field.options.name}">
-          <el-switch v-model="form.${field.options.name}" />
-          </el-form-item>
-#elseif($field.type == 'rate')
-        <el-form-item label="${field.options.label}" prop="${field.options.name}">
-          <el-rate v-model="form.${field.options.name}" />
-      </el-form-item>
-#elseif($field.type == 'slider')
-        <el-form-item label="${field.options.label}" prop="${field.options.name}">
-          <el-slider v-model="form.${field.options.name}" />
-      </el-form-item>
-#elseif($field.type == 'color')
-        <el-form-item label="${field.options.label}" prop="${field.options.name}">
-          <el-color-picker v-model="form.${field.options.name}" />
-      </el-form-item>
-#elseif($field.type == 'static-text' || $field.type == 'html-text')
-        <span>{{form.${field.options.name}}}</span>          
-#elseif($field.type == 'divider')
-      <el-divider />
-#else
-      <el-form-item label="${field.options.label}" prop="${field.options.name}">
-        <el-input v-model="form.${field.options.name}" placeholder="${field.options.placeholder}"/>
-      </el-form-item>
-#end
-  </el-col>
-#end
-</el-row>
-#end
-      </el-form>
-      <template #footer>
-        <span class="dialog-footer">
-          <el-button @click="visible = false" formDialogRef>取消</el-button>
-          <el-button type="primary" @click="onSubmit" formDialogRef>确认</el-button>
-        </span>
-      </template>
-    </el-dialog>
-</template>
-
-<script setup lang="ts" name="${ClassName}Dialog">
-import { useDict } from '/@/hooks/dict';
-import { useMessage } from "/@/hooks/message";
-import { getObj, addObj, putObj } from '/@/api/${moduleName}/${functionName}'
-import { rule } from '/@/utils/validate';
-const emit = defineEmits(['refresh']);
-
-// 定义变量内容
-const dataFormRef = ref();
-const visible = ref(false)
-// 定义字典
-#set($fieldDict=[])
-#foreach($key in $resultMap.keySet())
-#set($itemList = $resultMap.get($key))
-#foreach($field in $itemList)
-   #if($field.options.optionItemsDictType)
-        #set($void=$fieldDict.add($field.options.optionItemsDictType))
-    #end
-#end
-#end
-#if($fieldDict)
-const { $dict.format($fieldDict) } = useDict($dict.quotation($fieldDict))
-#end
-
-// 提交表单数据
-const form = reactive({
-		${pk.attrName}:"",
-#foreach($key in $resultMap.keySet())
-#set($itemList = $resultMap.get($key))
-#foreach($field in $itemList)
-    ${field.options.name}: "",
-#end
-#end
-});
-
-// 定义校验规则
-const dataRules = ref({
-#foreach($key in $resultMap.keySet())
-#set($itemList = $resultMap.get($key))
-#foreach($field in $itemList)
-#if($field.options.required && $field.options.validation)
-    ${field.options.name}: [{required: true, message: '${field.options.label}不能为空', trigger: 'blur'}, {{ validator: rule.${field.options.validation}, trigger: 'blur' }],
-#elseif($field.options.required)
-    ${field.options.name}: [{required: true, message: '${field.options.label}不能为空', trigger: 'blur'}],
-#elseif($field.options.validation)
-   ${field.options.name}: [{ validator: rule.${field.options.validation}, trigger: 'blur' }],
-#end
-#end
-#end
-})
-
-// 打开弹窗
-const openDialog = (id: string) => {
-  visible.value = true
-  form.${pk.attrName} = ''
-
-  // 重置表单数据
-    nextTick(() => {
-        dataFormRef.value?.resetFields();
-    });
-  
-  // 获取${className}信息
-  if (id) {
-    form.${pk.attrName} = id
-    get${className}Data(id)
-  }
-};
-
-// 提交
-const onSubmit = () => {
-  dataFormRef.value.validate((valid: boolean) => {
-    if (!valid) {
-      return false
-    }
-
-    // 更新
-    if (form.${pk.attrName}) {
-      putObj(form).then(() => {
-        useMessage().success('修改成功')
-        visible.value = false // 关闭弹窗
-        emit('refresh')
-      }).catch((err: any) => {
-        useMessage().error(err.msg)
-      })
-    } else {
-      addObj(form).then(() => {
-        useMessage().success('添加成功')
-        visible.value = false // 关闭弹窗
-        emit('refresh')
-      }).catch((err: any) => {
-        useMessage().error(err.msg)
-      })
-    }
-  })
-}
-
-// 初始化表单数据
-const get${className}Data = (id: string) => {
-  // 获取数据
-  getObj(id).then((res: any) => {
-    Object.assign(form, res.data)
-  })
-};
-
-// 暴露变量
-defineExpose({
-  openDialog
-});
-</script>

+ 3 - 1
multiple/主子Contoller.java

@@ -75,7 +75,9 @@ public class ${ClassName}Controller {
 #else
 #else
 #set($expression="Objects.nonNull")
 #set($expression="Objects.nonNull")
 #end
 #end
-#if($field.queryType == '=')
+#if($field.queryFormType == 'daterange' || $field.queryFormType == 'datetimerange')
+		wrapper.between(ArrayUtil.isNotEmpty(${className}.${getAttrName}Range()),${ClassName}Entity::$getAttrName,${className}.${getAttrName}Range()[0],${className}.${getAttrName}Range()[1]);
+#elseif($field.queryType == '=')
 		wrapper.eq($expression($var),${ClassName}Entity::$getAttrName,$var);
 		wrapper.eq($expression($var),${ClassName}Entity::$getAttrName,$var);
 #elseif( $field.queryType == 'like' )
 #elseif( $field.queryType == 'like' )
 		wrapper.like($expression($var),${ClassName}Entity::$getAttrName,$var);
 		wrapper.like($expression($var),${ClassName}Entity::$getAttrName,$var);

+ 12 - 2
multiple/主子表单.vue

@@ -63,6 +63,16 @@
             <el-date-picker type="datetime" placeholder="请选择#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end" v-model="form.${field.attrName}" :value-format="dateTimeStr"></el-date-picker>
             <el-date-picker type="datetime" placeholder="请选择#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end" v-model="form.${field.attrName}" :value-format="dateTimeStr"></el-date-picker>
           </el-form-item>
           </el-form-item>
         </el-col>
         </el-col>
+#elseif($field.formType == 'daterange')
+          <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end" prop="${field.attrName}">
+            <el-date-picker type="daterange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" v-model="form.${field.attrName}" :value-format="dateStr"></el-date-picker>
+          </el-form-item>
+        </el-col>
+#elseif($field.formType == 'datetimerange')
+          <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end" prop="${field.attrName}">
+            <el-date-picker type="datetimerange" range-separator="至" start-placeholder="开始时间" end-placeholder="结束时间" v-model="form.${field.attrName}" :value-format="dateTimeStr"></el-date-picker>
+          </el-form-item>
+        </el-col>
 #elseif($field.formType == 'number')
 #elseif($field.formType == 'number')
           <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end" prop="${field.attrName}">
           <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end" prop="${field.attrName}">
             <el-input-number :min="1" :max="1000" v-model="form.${field.attrName}" placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end"></el-input-number>
             <el-input-number :min="1" :max="1000" v-model="form.${field.attrName}" placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end"></el-input-number>
@@ -80,7 +90,7 @@
         </el-col>
         </el-col>
 #elseif($field.formType == 'editor')
 #elseif($field.formType == 'editor')
           <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end" prop="${field.attrName}">
           <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end" prop="${field.attrName}">
-            <editor v-model:get-html="form.${field.attrName}" placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end"></editor>
+            <editor v-if="visible" v-model:get-html="form.${field.attrName}" placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.fieldName}#end"></editor>
           </el-form-item>
           </el-form-item>
         </el-col>
         </el-col>
 #else
 #else
@@ -155,7 +165,7 @@ const form = reactive({
 #foreach($field in $formList)
 #foreach($field in $formList)
 #if($field.formType == 'number')
 #if($field.formType == 'number')
   ${field.attrName}: 0, // ${field.fieldComment}
   ${field.attrName}: 0, // ${field.fieldComment}
-#elseif($field.formType == 'checkbox')
+#elseif($field.formType == 'checkbox' || $field.formType == 'daterange' || $field.formType == 'datetimerange')
   ${field.attrName}: [], // ${field.fieldComment}
   ${field.attrName}: [], // ${field.fieldComment}
 #else
 #else
   ${field.attrName}: '', // ${field.fieldComment}
   ${field.attrName}: '', // ${field.fieldComment}

+ 32 - 10
multiple/主子表格.vue

@@ -22,21 +22,43 @@
           </el-form-item>
           </el-form-item>
 #elseif($field.queryFormType == 'date')
 #elseif($field.queryFormType == 'date')
           <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">
           <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">
-            <el-date-picker 
-              type="date" 
-              placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" 
+            <el-date-picker
+              type="date"
+              placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end"
+              :value-format="dateStr"
+              v-model="state.queryForm.${field.attrName}"
+            />
+          </el-form-item>
+#elseif($field.queryFormType == 'daterange')
+          <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}Range">
+            <el-date-picker
+              type="daterange"
+              range-separator="至"
+              start-placeholder="开始日期"
+              end-placeholder="结束日期"
+              v-model="state.queryForm.${field.attrName}Range"
               :value-format="dateStr"
               :value-format="dateStr"
-              v-model="state.queryForm.${field.attrName}">
-            </el-date-picker>
+            />
           </el-form-item>
           </el-form-item>
 #elseif($field.queryFormType == 'datetime')
 #elseif($field.queryFormType == 'datetime')
           <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">
           <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">
-            <el-date-picker 
-              type="datetime" 
-              placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" 
+            <el-date-picker
+              type="datetime"
+              placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end"
+              :value-format="dateTimeStr"
+              v-model="state.queryForm.${field.attrName}"
+            />
+          </el-form-item>
+#elseif($field.queryFormType == 'datetimerange')
+          <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}Range">
+            <el-date-picker
+              type="datetimerange"
+              range-separator="至"
+              start-placeholder="开始时间"
+              end-placeholder="结束时间"
+              v-model="state.queryForm.${field.attrName}Range"
               :value-format="dateTimeStr"
               :value-format="dateTimeStr"
-              v-model="state.queryForm.${field.attrName}">
-            </el-date-picker>
+            />
           </el-form-item>
           </el-form-item>
 #elseif($field.formType == 'radio')
 #elseif($field.formType == 'radio')
           <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">
           <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">

+ 17 - 2
multiple/主实体.java

@@ -11,7 +11,7 @@ import ${package}.common.core.util.TenantTable;
 #foreach($import in $importList)
 #foreach($import in $importList)
 import $import;
 import $import;
 #end
 #end
-import cn.idev.excel..annotation.ExcelIgnore;
+import cn.idev.excel.annotation.ExcelIgnore;
 import com.github.yulichang.annotation.EntityMapping;
 import com.github.yulichang.annotation.EntityMapping;
 import java.util.List;
 import java.util.List;
 
 
@@ -53,9 +53,24 @@ public class ${ClassName}Entity extends Model<${ClassName}Entity> {
     @Schema(description="$comment"#if($field.hidden),hidden=$field.hidden#end)
     @Schema(description="$comment"#if($field.hidden),hidden=$field.hidden#end)
 #if($field.formType == 'checkbox')
 #if($field.formType == 'checkbox')
     private ${field.attrType}[] $field.attrName;
     private ${field.attrType}[] $field.attrName;
+#elseif($field.formType == 'daterange' || $field.formType == 'datetimerange')
+    @TableField(typeHandler = JacksonTypeHandler.class)
+    private String[] $field.attrName;
 #else
 #else
     private $field.attrType $field.attrName;
     private $field.attrType $field.attrName;
-#end    
+#end
+#end
+#foreach ($field in $queryList)
+#if($field.queryFormType == 'daterange' || $field.queryFormType == 'datetimerange')
+#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end
+
+	/**
+	* $comment 查询范围
+	*/
+    @TableField(exist = false)
+    @Schema(description="$comment 查询范围",hidden=true)
+    private String[] ${field.attrName}Range;
+#end
 #end
 #end
     @ExcelIgnore
     @ExcelIgnore
     @TableField(exist = false)
     @TableField(exist = false)

+ 3 - 1
single/Controller.java

@@ -76,7 +76,9 @@ public class ${ClassName}Controller {
 #else
 #else
 #set($expression="Objects.nonNull")
 #set($expression="Objects.nonNull")
 #end
 #end
-#if($field.queryType == '=')
+#if($field.queryFormType == 'daterange' || $field.queryFormType == 'datetimerange')
+		wrapper.between(ArrayUtil.isNotEmpty(${className}.${getAttrName}Range()),${ClassName}Entity::$getAttrName,${className}.${getAttrName}Range()[0],${className}.${getAttrName}Range()[1]);
+#elseif($field.queryType == '=')
 		wrapper.eq($expression($var),${ClassName}Entity::$getAttrName,$var);
 		wrapper.eq($expression($var),${ClassName}Entity::$getAttrName,$var);
 #elseif( $field.queryType == 'like' )
 #elseif( $field.queryType == 'like' )
 		wrapper.like($expression($var),${ClassName}Entity::$getAttrName,$var);
 		wrapper.like($expression($var),${ClassName}Entity::$getAttrName,$var);

+ 16 - 1
single/实体.java

@@ -50,8 +50,23 @@ public class ${ClassName}Entity extends Model<${ClassName}Entity> {
     @Schema(description="$comment"#if($field.hidden),hidden=$field.hidden#end)
     @Schema(description="$comment"#if($field.hidden),hidden=$field.hidden#end)
 #if($field.formType == 'checkbox')
 #if($field.formType == 'checkbox')
     private ${field.attrType}[] $field.attrName;
     private ${field.attrType}[] $field.attrName;
+#elseif($field.formType == 'daterange' || $field.formType == 'datetimerange')
+    @TableField(typeHandler = JacksonTypeHandler.class)
+    private String[] $field.attrName;
 #else
 #else
     private $field.attrType $field.attrName;
     private $field.attrType $field.attrName;
-#end    
+#end
+#end
+#foreach ($field in $queryList)
+#if($field.queryFormType == 'daterange' || $field.queryFormType == 'datetimerange')
+#if(${field.fieldComment})#set($comment=${field.fieldComment})#else #set($comment=${field.attrName})#end
+
+	/**
+	* $comment 查询范围
+	*/
+    @TableField(exist = false)
+    @Schema(description="$comment 查询范围",hidden=true)
+    private String[] ${field.attrName}Range;
+#end
 #end
 #end
 }
 }

+ 12 - 2
single/表单.vue

@@ -1,7 +1,7 @@
 <template>
 <template>
   <el-dialog :title="form.${pk.attrName} ? '编辑' : '新增'" v-model="visible"
   <el-dialog :title="form.${pk.attrName} ? '编辑' : '新增'" v-model="visible"
     :close-on-click-modal="false" draggable>
     :close-on-click-modal="false" draggable>
-    <el-form ref="dataFormRef" :model="form" :rules="dataRules" formDialogRef label-width="90px" v-loading="loading">
+    <el-form ref="dataFormRef" :model="form" :rules="dataRules" label-width="90px" v-loading="loading">
       <el-row :gutter="24">
       <el-row :gutter="24">
 #foreach($field in $formList)
 #foreach($field in $formList)
 #if($field.attrName != ${pk.attrName})
 #if($field.attrName != ${pk.attrName})
@@ -64,6 +64,16 @@
             <el-date-picker type="datetime" placeholder="请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" v-model="form.${field.attrName}" :value-format="dateTimeStr"></el-date-picker>
             <el-date-picker type="datetime" placeholder="请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" v-model="form.${field.attrName}" :value-format="dateTimeStr"></el-date-picker>
           </el-form-item>
           </el-form-item>
         </el-col>
         </el-col>
+#elseif($field.formType == 'daterange')
+          <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">
+            <el-date-picker type="daterange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" v-model="form.${field.attrName}" :value-format="dateStr"></el-date-picker>
+          </el-form-item>
+        </el-col>
+#elseif($field.formType == 'datetimerange')
+          <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">
+            <el-date-picker type="datetimerange" range-separator="至" start-placeholder="开始时间" end-placeholder="结束时间" v-model="form.${field.attrName}" :value-format="dateTimeStr"></el-date-picker>
+          </el-form-item>
+        </el-col>
 #elseif($field.formType == 'number')
 #elseif($field.formType == 'number')
           <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">
           <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">
             <el-input-number :min="1" :max="1000" v-model="form.${field.attrName}" placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end"></el-input-number>
             <el-input-number :min="1" :max="1000" v-model="form.${field.attrName}" placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end"></el-input-number>
@@ -128,7 +138,7 @@ const form = reactive({
 #foreach($field in $formList)
 #foreach($field in $formList)
 #if($field.formType == 'number')
 #if($field.formType == 'number')
   ${field.attrName}: 0, // ${field.fieldComment}
   ${field.attrName}: 0, // ${field.fieldComment}
-#elseif($field.formType == 'checkbox')
+#elseif($field.formType == 'checkbox' || $field.formType == 'daterange' || $field.formType == 'datetimerange')
   ${field.attrName}: [], // ${field.fieldComment}
   ${field.attrName}: [], // ${field.fieldComment}
 #else
 #else
   ${field.attrName}: '', // ${field.fieldComment}
   ${field.attrName}: '', // ${field.fieldComment}

+ 30 - 8
single/表格.vue

@@ -23,22 +23,44 @@
           </el-form-item>
           </el-form-item>
 #elseif($field.queryFormType == 'date')
 #elseif($field.queryFormType == 'date')
           <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">
           <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">
-            <el-date-picker 
-              type="date" 
-              placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" 
+            <el-date-picker
+              type="date"
+              placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end"
               v-model="state.queryForm.${field.attrName}"
               v-model="state.queryForm.${field.attrName}"
               :value-format="dateStr"
               :value-format="dateStr"
             />
             />
           </el-form-item>
           </el-form-item>
+#elseif($field.queryFormType == 'daterange')
+          <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}Range">
+            <el-date-picker
+              type="daterange"
+              range-separator="至"
+              start-placeholder="开始日期"
+              end-placeholder="结束日期"
+              v-model="state.queryForm.${field.attrName}Range"
+              :value-format="dateStr"
+            />
+          </el-form-item>
 #elseif($field.queryFormType == 'datetime')
 #elseif($field.queryFormType == 'datetime')
           <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">
           <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">
-            <el-date-picker 
-              type="datetime" 
-              placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" 
+            <el-date-picker
+              type="datetime"
+              placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end"
               v-model="state.queryForm.${field.attrName}"
               v-model="state.queryForm.${field.attrName}"
               :value-format="dateTimeStr"
               :value-format="dateTimeStr"
             />
             />
           </el-form-item>
           </el-form-item>
+#elseif($field.queryFormType == 'datetimerange')
+          <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}Range">
+            <el-date-picker
+              type="datetimerange"
+              range-separator="至"
+              start-placeholder="开始时间"
+              end-placeholder="结束时间"
+              v-model="state.queryForm.${field.attrName}Range"
+              :value-format="dateTimeStr"
+            />
+          </el-form-item>
 #elseif($field.formType == 'radio')
 #elseif($field.formType == 'radio')
           <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">
           <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">
             <el-radio-group v-model="state.queryForm.${field.attrName}">
             <el-radio-group v-model="state.queryForm.${field.attrName}">
@@ -127,7 +149,7 @@
         border 
         border 
         :cell-style="tableStyle.cellStyle" 
         :cell-style="tableStyle.cellStyle" 
         :header-cell-style="tableStyle.headerCellStyle"
         :header-cell-style="tableStyle.headerCellStyle"
-        @selection-change="selectionChangHandle"
+        @selection-change="selectionChangeHandle"
         @sort-change="sortChangeHandle"
         @sort-change="sortChangeHandle"
       >
       >
         <el-table-column type="selection" width="40" align="center" />
         <el-table-column type="selection" width="40" align="center" />
@@ -279,7 +301,7 @@ const exportExcel = () => {
  * 表格多选事件处理
  * 表格多选事件处理
  * @param objs 选中的数据行
  * @param objs 选中的数据行
  */
  */
-const selectionChangHandle = (objs: { $pk.attrName: string }[]) => {
+const selectionChangeHandle = (objs: { $pk.attrName: string }[]) => {
   selectObjs.value = objs.map(({ $pk.attrName }) => $pk.attrName);
   selectObjs.value = objs.map(({ $pk.attrName }) => $pk.attrName);
   multiple.value = !objs.length;
   multiple.value = !objs.length;
 };
 };