Browse Source

feat:测试自动生成弹窗

DOVER-GLOBAL\10093976 1 day ago
parent
commit
94dd371f68

+ 149 - 18
admin.ui.plus-master/src/views/admin/yujing/alarmRules/test.vue

@@ -75,7 +75,7 @@
           </el-form>
           
           <hr>
-          
+
           
 <el-row justify="space-between" class="submit-button" style="margin-bottom: -9px;">
 <el-button type="primary" icon="ele-Search" @click="onQuery"> 查询 </el-button>
@@ -93,8 +93,9 @@
 <!--表格-->
       <el-col  :xs="24" >
         <el-card style="height: 70vh" class="my-fill mt8" shadow="hover">
+        <el-table v-loading="state.loading" stripe :data="state.tableModel" row-key="id" style="width: 100%">
 <el-table-column type="selection" width="50"></el-table-column>
-<el-table v-loading="state.loading" stripe :data="state.tableModel" row-key="id" style="width: 100%">
+
         <el-table-column v-for="column in state.dynamicColumns" :key="column.prop" :prop="column.prop" :label="column.label"  >
         </el-table-column> 
 <el-table-column label="操作"  fixed="right" header-align="center" align="center" class="right-operation" width="140">
@@ -126,10 +127,10 @@
 </template>
             </el-table-column>
 </el-table>
-<!-- <div class="my-flex my-flex-end" style="margin-top: 20px">
+<div class="my-flex my-flex-end" style="margin-top: 20px">
             <el-pagination
-              v-model:currentPage="state.pageInput.CurrentPage"
-              v-model:page-size="state.pageInput.PageSize"
+              v-model:currentPage="pageState.pageInput.CurrentPage"
+              v-model:page-size="pageState.pageInput.PageSize"
               :total="state.total"
               :page-sizes="[10, 15, 20, 50, 100]"
               small
@@ -138,25 +139,99 @@
               @current-change="onCurrentChange"
               layout="total, sizes, prev, pager, next, jumper"
             />
-          </div> -->
+          </div>
 </el-card>
       </el-col>
+<!-- 弹窗 -->
+    <el-dialog
+      v-model="state.dialogVisible"
+      :title="state.isEdit ? '修改BoardTestRecordDto' : '添加BoardTestRecordDto'"
+      width="500px"
+      :before-close="handleDialogClose"
+    >
+      <el-form
+        ref="formRef"
+        :model="state.formData"
+        :rules="state.rules"
+        label-width="100px"
+      >
+<el-form-item label="序列号" prop="serno">
+          <el-input v-model="state.formData.serno" placeholder="请输入序列号"></el-input>
+        </el-form-item>
+<el-form-item label="外部序列号" prop="exserno">
+          <el-input v-model="state.formData.exserno" placeholder="请输入外部序列号"></el-input>
+        </el-form-item>
+<el-form-item label="主板类型" prop="boardType">
+          <el-input v-model="state.formData.boardType" placeholder="请输入主板类型"></el-input>
+        </el-form-item>
+<el-form-item label="主板名称" prop="boardName">
+          <el-input v-model="state.formData.boardName" placeholder="请输入主板名称"></el-input>
+        </el-form-item>
+<el-form-item label="功能码" prop="functionCode">
+          <el-input v-model="state.formData.functionCode" placeholder="请输入功能码"></el-input>
+        </el-form-item>
+<el-form-item label="功能名称" prop="functionName">
+          <el-input v-model="state.formData.functionName" placeholder="请输入功能名称"></el-input>
+        </el-form-item>
+<el-form-item label="检测类型" prop="testType">
+          <el-input v-model="state.formData.testType" placeholder="请输入检测类型"></el-input>
+        </el-form-item>
+<el-form-item label="检测时间" prop="time">
+          <el-input v-model="state.formData.time" placeholder="请输入检测时间"></el-input>
+        </el-form-item>
+<el-form-item label="测试结果" prop="result">
+          <el-input v-model="state.formData.result" placeholder="请输入测试结果"></el-input>
+        </el-form-item>
+<el-form-item label="测试功能数" prop="testNum">
+          <el-input v-model="state.formData.testNum" placeholder="请输入测试功能数"></el-input>
+        </el-form-item>
+<el-form-item label="测试成功功能数" prop="testSuccessNum">
+          <el-input v-model="state.formData.testSuccessNum" placeholder="请输入测试成功功能数"></el-input>
+        </el-form-item>
+<el-form-item label="测试员" prop="user">
+          <el-input v-model="state.formData.user" placeholder="请输入测试员"></el-input>
+        </el-form-item>
+<el-form-item label="测试耗时" prop="duration">
+          <el-input v-model="state.formData.duration" placeholder="请输入测试耗时"></el-input>
+        </el-form-item>
+<el-form-item label="备注" prop="info">
+          <el-input v-model="state.formData.info" placeholder="请输入备注"></el-input>
+        </el-form-item>
+</el-form>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="handleDialogClose">取消</el-button>
+          <el-button type="primary" @click="handleSubmit">确定</el-button>
+        </span>
+      </template>
+    </el-dialog>
 </el-row>
     </div>
   </template>
   <script setup lang="ts">
   import {onBeforeMount, onMounted, reactive, ref, watch} from "vue";
   import eventBus from "/@/utils/mitt";
-  import {Api} from "/@/api/admin/AlarmService/testApi";
-import { BoardTestRecordDto } from "/@/api/admin/AlarmService/testDto";
-
-import type { pageInput } from "/@/api/admin/AlarmService/testDto";
+  import {Api} from "/@/api/code/api";
+  import { useDynamicPageSize } from "/@/composables/useDynamicPageSize";
 
+  // 使用组合式函数获取分页状态
+const pageState = useDynamicPageSize(10, 15);
+import { BoardTestRecordDto } from "/@/api/code/dto";
+    import type { pageInput } from "/@/api/code/dto"
+    
 /**数据对象*/
   const state = reactive({
     /**加载显示 */
     loading: false,
-    /**条件查询模块 */
+/** 弹窗显示状态 */
+    dialogVisible: false,
+    /** 是否是编辑状态 */
+    isEdit: false,
+    /** 表单数据 */
+    formData: {} as BoardTestRecordDto,
+    /** 表单验证规则 */
+    rules: {},
+/**条件查询模块 */
       filter: {
 /**serno */
         serno: "",
@@ -205,6 +280,8 @@ tableModel: [] as BoardTestRecordDto,
     total: 0,
 })
   onMounted(() => {
+    // 初始化分页大小
+    Data.pageInput.pageSize = pageState.pageInput.pageSize; 
     init()
     eventBus.off('refreshView')
     eventBus.on('refreshView', async () => {
@@ -226,14 +303,18 @@ tableModel: [] as BoardTestRecordDto,
         /**初始化 */
         const init = async () => {
           state.loading = true
-const res:any = await new Api().getList({...state.pageInput, Filter:state.filter})
+const res:any = await new Api().getList({...pageState.pageInput, Filter:state.filter})
             state.total = res?.data?.total ?? 0
 state.tableModel = res?.data?.list ?? []
           state.loading = false
         }
 /**添加 */
-        const onAdd=()=>{}
-/**批量删除 */
+                const onAdd = () => {
+          state.isEdit = false;
+          state.formData = {} as BoardTestRecordDto;
+          state.dialogVisible = true;
+        };
+        /**批量删除 */
         const ondelete=()=>{}
 /**重置 */
         const onReset=()=>{}
@@ -248,11 +329,61 @@ state.tableModel = res?.data?.list ?? []
 /**批量审核 */
         const onBatReview=()=>{}
 /**编辑 */
-      const onDateUpdate=(row)=>{}
+        const onDateUpdate = (row: BoardTestRecordDto) => {
+          state.isEdit = true;
+          state.formData = { ...row };
+          state.dialogVisible = true;
+        }
 /**详情 */
-      const onDataDetail=(row)=>{}
+        const onDataDetail=(row)=>{}
 /**删除 */
-      const onDataDelete=(row)=>{}
-</script>
+        const onDataDelete=(row)=>{}
+/** 关闭弹窗 */
+    const handleDialogClose = () => {
+      state.dialogVisible = false;
+    };
+    
+    /** 提交表单 */
+    const handleSubmit = () => {
+      // Add your submit logic here
+      state.dialogVisible = false;
+    };
+
+  /**
+* 页条变化
+* @param val
+*/
+const onSizeChange = (val: number) => {
+  Data.pageInput.pageSize = val
+  //需按照页面对象修改Data
+  init()
+}
+
+/**
+ * 页数 变化
+ * @param val
+ */
+const onCurrentChange = (val: number) => {
+  Data.pageInput.currentPage = val
+  //需按照页面对象修改Data
+  init()
+}
+  </script>
 <style scoped lang="scss">
+  .el-input,
+.el-select {
+  width: 240px;
+}
+
+/* 输入框标签固定四个字符宽度 */
+::v-deep .el-form-item__label {
+  // 字体大小14,5个字符,12px右间距
+  width: 14*5px+12px;
+  justify-content: start;
+}
+
+/* 数据表头 设置灰色样式 */
+::v-deep .el-table th.el-table__cell {
+  background-color: #F6F6F6;
+}
   </style>

+ 645 - 0
admin.ui.plus-master/src/views/example/codeGeneration/dialog.vue

@@ -0,0 +1,645 @@
+<template>
+  <div class="layout">
+    <h1 style="margin-top: 10px;margin-bottom: 10px;">弹窗配置</h1>
+    <div style="color: #505050;margin-bottom: 20px;">配置弹窗的表单项和功能</div>
+    
+    <!-- 接口选择部分 -->
+    <el-card class="mt8" shadow="never" :body-style="{ paddingBottom: '0' }">
+      <div>
+        <el-form :inline="true" @submit.stop.prevent>
+          <el-form-item label="接口地址" style="width: 60%;">
+            <el-input v-model="state.filter.name" placeholder="请输入接口地址" @keyup.enter="onQuery" />
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" icon="ele-Search" @click="onQuery"> 查询 </el-button>
+          </el-form-item>
+        </el-form>
+      </div>
+      <div>
+        <el-form :inline="true" @submit.stop.prevent>
+          <el-form-item label="弹窗接口来源" style="width: 70%;">
+            <el-select v-model="state.filter.api" placeholder="请选择弹窗接口来源" @change="onChange(state.filter.api)">
+              <el-option v-for="(value, key) in state.api" :key="key" :label="value.api+' '+value.summary" :value="value.api" />
+            </el-select>
+          </el-form-item>
+        </el-form>
+      </div>
+    </el-card>
+    
+    <!-- 弹窗功能配置 -->
+    <el-card class="mt8" shadow="never" :body-style="{ paddingBottom: '0' }">
+      <div>
+        <el-form :inline="true" @submit.stop.prevent>
+          <el-form-item label="弹窗功能配置" style="width: 100%;"></el-form-item>
+          <el-form-item>
+            <el-checkbox v-model="state.dialogConfig.hasTitle">显示标题</el-checkbox>
+            <el-checkbox v-model="state.dialogConfig.hasFooter">显示底部按钮</el-checkbox>
+            <el-checkbox v-model="state.dialogConfig.hasCancelBtn">显示取消按钮</el-checkbox>
+          </el-form-item>
+        </el-form>
+      </div>
+      <div>
+        <el-form :inline="true" @submit.stop.prevent>
+          <el-form-item label="弹窗宽度" style="width: 30%;">
+            <el-input v-model="state.dialogConfig.width" placeholder="例如: 500px"></el-input>
+          </el-form-item>
+          <el-form-item label="标题变量名" style="width: 30%;">
+            <el-input v-model="state.dialogConfig.titleVar" placeholder="例如: dialogTitle"></el-input>
+          </el-form-item>
+          <el-form-item label="显示变量名" style="width: 30%;">
+            <el-input v-model="state.dialogConfig.visibleVar" placeholder="例如: dialogVisible"></el-input>
+          </el-form-item>
+        </el-form>
+      </div>
+    </el-card>
+    
+    <!-- 表单项配置 -->
+    <el-card class="mt8" shadow="never" :body-style="{ paddingBottom: '0' }">
+      <div>
+        <el-form :inline="true" @submit.stop.prevent>
+          <el-form-item label="表单项配置" style="width: 100%;"></el-form-item>
+          <el-form-item>
+            <el-table :data="state.formItems" style="width: 100%">
+              <el-table-column prop="name" label="字段名" width="120"></el-table-column>
+              <el-table-column prop="description" label="描述" width="180"></el-table-column>
+              <el-table-column label="是否包含" width="100">
+                <template #default="{ row }">
+                  <el-switch v-model="row.include" @change="changeItem(row)"></el-switch>
+                </template>
+              </el-table-column>
+              <el-table-column label="表单类型" width="150">
+                <template #default="{ row }">
+                  <el-select v-model="row.type" placeholder="选择类型" @change="changeItemType(row)">
+                    <el-option label="输入框" value="input"></el-option>
+                    <el-option label="数字输入框" value="number"></el-option>
+                    <el-option label="下拉框" value="select"></el-option>
+                    <el-option label="日期选择器" value="date"></el-option>
+                    <el-option label="日期时间选择器" value="datetime"></el-option>
+                    <el-option label="日期范围" value="daterange"></el-option>
+                    <el-option label="开关" value="switch"></el-option>
+                    <el-option label="多选框" value="checkbox"></el-option>
+                    <el-option label="单选框" value="radio"></el-option>
+                    <el-option label="文本域" value="textarea"></el-option>
+                  </el-select>
+                </template>
+              </el-table-column>
+              <el-table-column label="是否必填" width="100">
+                <template #default="{ row }">
+                  <el-switch v-model="row.required" @change="changeItem(row)"></el-switch>
+                </template>
+              </el-table-column>
+              <el-table-column label="验证规则" width="150">
+                <template #default="{ row }">
+                  <el-select v-model="row.rule" placeholder="选择规则" @change="changeItemRule(row)">
+                    <el-option label="无" value=""></el-option>
+                    <el-option label="必填" value="required"></el-option>
+                    <el-option label="邮箱" value="email"></el-option>
+                    <el-option label="手机号" value="phone"></el-option>
+                    <el-option label="数字" value="number"></el-option>
+                    <el-option label="自定义" value="custom"></el-option>
+                  </el-select>
+                </template>
+              </el-table-column>
+              <el-table-column label="操作" width="120">
+                <template #default="{ row }">
+                  <el-button size="small" @click="editItemOptions(row)">选项配置</el-button>
+                </template>
+              </el-table-column>
+            </el-table>
+          </el-form-item>
+        </el-form>
+      </div>
+    </el-card>
+    
+    <!-- 生成按钮 -->
+    <div style="display: flex;justify-content: center;align-items: center;">
+      <el-button style="margin-top: 20px;width: 264px;height: 42px;" type="primary" @click="generateDialogCode">生成弹窗代码</el-button>
+    </div>
+    
+    <!-- 代码预览弹窗 -->
+    <el-dialog v-model="state.codePreviewVisible" title="弹窗代码预览" width="70%" top="5vh">
+      <el-tabs type="border-card">
+        <el-tab-pane label="弹窗模板">
+          <pre>{{ state.generatedCode.template }}</pre>
+        </el-tab-pane>
+        <el-tab-pane label="脚本部分">
+          <pre>{{ state.generatedCode.script }}</pre>
+        </el-tab-pane>
+        <el-tab-pane label="样式部分">
+          <pre>{{ state.generatedCode.style }}</pre>
+        </el-tab-pane>
+      </el-tabs>
+      <template #footer>
+        <el-button @click="state.codePreviewVisible = false">关闭</el-button>
+        <el-button type="primary" @click="downloadCode">下载代码</el-button>
+      </template>
+    </el-dialog>
+
+    <!-- 选项配置弹窗 -->
+    <el-dialog v-model="state.optionsDialogVisible" title="选项配置">
+      <el-form>
+        <el-form-item label="字段名">
+          <el-input v-model="state.currentItem.name" disabled></el-input>
+        </el-form-item>
+        <el-form-item label="选项列表">
+          <el-button type="primary" @click="addOption">添加选项</el-button>
+          <div v-for="(option, index) in state.currentItem.options" :key="index" style="margin-top: 10px;">
+            <el-input v-model="option.label" placeholder="选项标签" style="width: 200px; margin-right: 10px;"></el-input>
+            <el-input v-model="option.value" placeholder="选项值" style="width: 200px; margin-right: 10px;"></el-input>
+            <el-button type="danger" @click="removeOption(index)">删除</el-button>
+          </div>
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <el-button @click="state.optionsDialogVisible = false">取消</el-button>
+        <el-button type="primary" @click="saveOptions">保存</el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { reactive, onMounted } from 'vue'
+import { ElMessage } from 'element-plus'
+
+interface ApiItem {
+  api: string
+  summary: string
+  method: string
+  requestBody?: {
+    content?: {
+      'application/json'?: {
+        schema?: {
+          $ref?: string
+          properties?: Record<string, any>
+        }
+      }
+    }
+  }
+}
+
+interface FormItem {
+  name: string
+  description: string
+  type: string
+  format?: string
+  include: boolean
+  required: boolean
+  rule: string
+  options?: Array<{ label: string, value: string }>
+}
+
+const state = reactive({
+  loading: false,
+  filter: {
+    name: 'http://dev.hsfuel.com:8070/app/swagger/app/swagger.json',
+    api: ''
+  },
+  api: [] as ApiItem[],
+  swaggerData: null as any,
+  dialogConfig: {
+    hasTitle: true,
+    hasFooter: true,
+    hasCancelBtn: true,
+    width: '500px',
+    titleVar: 'dialogTitle',
+    visibleVar: 'dialogVisible'
+  },
+  formItems: [] as FormItem[],
+  codePreviewVisible: false,
+  generatedCode: {
+    template: '',
+    script: '',
+    style: ''
+  },
+  optionsDialogVisible: false,
+  currentItem: {
+    name: '',
+    description: '',
+    type: '',
+    options: [] as Array<{ label: string, value: string }>
+  }
+})
+
+// 从接口获取数据
+const onQuery = async () => {
+  try {
+    state.loading = true
+    const response = await fetch(state.filter.name)
+    const swaggerJson = await response.json()
+    state.swaggerData = swaggerJson
+    state.api = []
+    const { paths } = swaggerJson
+    
+    for (const path in paths) {
+      if ('post' in paths[path] || 'put' in paths[path]) {
+        const method = paths[path].post ? 'post' : 'put'
+        const operation = paths[path][method]
+        
+        state.api.push({
+          api: path,
+          summary: operation.summary || '',
+          method: method.toUpperCase(),
+          requestBody: operation.requestBody
+        })
+      }
+    }
+    
+    ElMessage.success('接口加载成功')
+  } catch (error) {
+    console.error('获取接口失败:', error)
+    ElMessage.error('获取接口失败')
+  } finally {
+    state.loading = false
+  }
+}
+
+// 根据$ref获取schema定义
+const getSchemaByRef = (ref: string) => {
+  if (!state.swaggerData || !ref) return null
+  const refPath = ref.replace('#/', '').split('/')
+  let current = state.swaggerData
+  for (const path of refPath) {
+    current = current[path]
+    if (!current) return null
+  }
+  return current
+}
+
+// 解析请求体属性
+const parseRequestBodyProperties = (apiItem: ApiItem) => {
+  if (!apiItem.requestBody?.content?.['application/json']?.schema) return []
+  
+  const schema = apiItem.requestBody.content['application/json'].schema
+  let properties = {}
+  let requiredFields: string[] = []
+  
+  if (schema.$ref) {
+    const refSchema = getSchemaByRef(schema.$ref)
+    if (refSchema?.properties) {
+      properties = refSchema.properties
+      requiredFields = refSchema.required || []
+    }
+  } else if (schema.properties) {
+    properties = schema.properties
+    requiredFields = schema.required || []
+  }
+  
+  return Object.entries(properties).map(([name, prop]: [string, any]) => {
+    const formItem: FormItem = {
+      name,
+      description: prop.description || name,
+      type: prop.type || 'string',
+      format: prop.format,
+      include: true,
+      required: requiredFields.includes(name),
+      rule: requiredFields.includes(name) ? 'required' : ''
+    }
+    
+    // 根据类型和format设置默认的表单组件类型
+    if (formItem.type === 'string') {
+      if (formItem.format === 'date-time') {
+        formItem.type = 'datetime'
+      } else if (formItem.format === 'date') {
+        formItem.type = 'date'
+      } else if (prop.enum) {
+        formItem.type = 'select'
+        formItem.options = prop.enum.map((value: string) => ({
+          label: value,
+          value
+        }))
+      } else if (prop.maxLength > 100) {
+        formItem.type = 'textarea'
+      }
+    } else if (formItem.type === 'integer' || formItem.type === 'number') {
+      formItem.type = 'number'
+    } else if (formItem.type === 'boolean') {
+      formItem.type = 'switch'
+    }
+    
+    return formItem
+  })
+}
+
+// 选择接口后解析请求体
+const onChange = (apiPath: string) => {
+  if (!apiPath) {
+    state.formItems = []
+    return
+  }
+  
+  const selectedApi = state.api.find(item => item.api === apiPath)
+  if (!selectedApi) return
+  
+  state.formItems = parseRequestBodyProperties(selectedApi)
+}
+
+const changeItem = (item: FormItem) => {
+  console.log('表单项变更:', item)
+}
+
+const changeItemType = (item: FormItem) => {
+  console.log('表单项类型变更:', item)
+  // 如果是选择类型,添加默认选项
+  if ((item.type === 'select' || item.type === 'radio' || item.type === 'checkbox') && !item.options) {
+    item.options = [{ label: '选项1', value: '1' }, { label: '选项2', value: '2' }]
+  }
+}
+
+const changeItemRule = (item: FormItem) => {
+  console.log('验证规则变更:', item)
+}
+
+// 编辑选项配置
+const editItemOptions = (item: FormItem) => {
+  if (!['select', 'radio', 'checkbox'].includes(item.type)) {
+    ElMessage.warning('当前字段类型不支持选项配置')
+    return
+  }
+  
+  state.currentItem = {
+    name: item.name,
+    description: item.description,
+    type: item.type,
+    options: item.options ? [...item.options] : []
+  }
+  state.optionsDialogVisible = true
+}
+
+// 添加选项
+const addOption = () => {
+  state.currentItem.options.push({
+    label: '',
+    value: ''
+  })
+}
+
+// 删除选项
+const removeOption = (index: number) => {
+  state.currentItem.options.splice(index, 1)
+}
+
+// 保存选项
+const saveOptions = () => {
+  const item = state.formItems.find(item => item.name === state.currentItem.name)
+  if (item) {
+    item.options = state.currentItem.options.filter(opt => opt.label && opt.value)
+  }
+  state.optionsDialogVisible = false
+  ElMessage.success('选项配置已保存')
+}
+
+// 生成弹窗代码
+const generateDialogCode = () => {
+  if (!state.filter.api) {
+    ElMessage.error('请选择弹窗接口来源')
+    return
+  }
+  
+  const selectedItems = state.formItems.filter(item => item.include)
+  if (selectedItems.length === 0) {
+    ElMessage.error('请至少选择一个表单项')
+    return
+  }
+  
+  // 生成模板代码
+  let templateCode = `<el-dialog
+  v-model="${state.dialogConfig.visibleVar}"
+  :title="${state.dialogConfig.titleVar}"
+  width="${state.dialogConfig.width}"
+  :before-close="handleDialogClose"
+>
+  <el-form
+    ref="formRef"
+    :model="formData"
+    :rules="rules"
+    label-width="100px"
+  >\n`
+  
+  // 添加表单项
+  selectedItems.forEach(item => {
+    templateCode += `    <el-form-item label="${item.description}" prop="${item.name}">\n`
+    
+    switch (item.type) {
+      case 'input':
+        templateCode += `      <el-input v-model="formData.${item.name}" placeholder="请输入${item.description}"></el-input>\n`
+        break
+      case 'number':
+        templateCode += `      <el-input-number v-model="formData.${item.name}" placeholder="请输入${item.description}"></el-input-number>\n`
+        break
+      case 'select':
+        templateCode += `      <el-select v-model="formData.${item.name}" placeholder="请选择${item.description}" clearable>\n`
+        if (item.options) {
+          item.options.forEach(opt => {
+            templateCode += `        <el-option label="${opt.label}" value="${opt.value}"></el-option>\n`
+          })
+        }
+        templateCode += `      </el-select>\n`
+        break
+      case 'date':
+        templateCode += `      <el-date-picker
+        v-model="formData.${item.name}"
+        type="date"
+        placeholder="请选择${item.description}"
+        value-format="YYYY-MM-DD"
+      ></el-date-picker>\n`
+        break
+      case 'datetime':
+        templateCode += `      <el-date-picker
+        v-model="formData.${item.name}"
+        type="datetime"
+        placeholder="请选择${item.description}"
+        value-format="YYYY-MM-DD HH:mm:ss"
+      ></el-date-picker>\n`
+        break
+      case 'switch':
+        templateCode += `      <el-switch v-model="formData.${item.name}"></el-switch>\n`
+        break
+      case 'textarea':
+        templateCode += `      <el-input v-model="formData.${item.name}" type="textarea" :rows="3" placeholder="请输入${item.description}"></el-input>\n`
+        break
+      case 'radio':
+        templateCode += `      <el-radio-group v-model="formData.${item.name}">\n`
+        if (item.options) {
+          item.options.forEach(opt => {
+            templateCode += `        <el-radio label="${opt.value}">${opt.label}</el-radio>\n`
+          })
+        }
+        templateCode += `      </el-radio-group>\n`
+        break
+      case 'checkbox':
+        templateCode += `      <el-checkbox-group v-model="formData.${item.name}">\n`
+        if (item.options) {
+          item.options.forEach(opt => {
+            templateCode += `        <el-checkbox label="${opt.value}">${opt.label}</el-checkbox>\n`
+          })
+        }
+        templateCode += `      </el-checkbox-group>\n`
+        break
+      default:
+        templateCode += `      <el-input v-model="formData.${item.name}" placeholder="请输入${item.description}"></el-input>\n`
+    }
+    
+    templateCode += `    </el-form-item>\n\n`
+  })
+  
+  // 添加底部按钮
+  if (state.dialogConfig.hasFooter) {
+    templateCode += `  </el-form>
+  <template #footer>
+    <span class="dialog-footer">\n`
+    
+    if (state.dialogConfig.hasCancelBtn) {
+      templateCode += `      <el-button @click="handleDialogClose">取消</el-button>\n`
+    }
+    
+    templateCode += `      <el-button type="primary" @click="handleSubmit">确定</el-button>
+    </span>
+  </template>
+</el-dialog>`
+  } else {
+    templateCode += `  </el-form>
+</el-dialog>`
+  }
+  
+  // 生成脚本代码
+  let scriptCode = `<script setup lang="ts">
+import { reactive, ref } from 'vue'
+import type { FormInstance, FormRules } from 'element-plus'
+
+const ${state.dialogConfig.visibleVar} = ref(false)
+const ${state.dialogConfig.titleVar} = ref('')
+const formRef = ref<FormInstance>()
+const formData = reactive({\n`
+  
+  // 添加表单数据
+  selectedItems.forEach(item => {
+    if (item.type === 'checkbox') {
+      scriptCode += `  ${item.name}: [] as string[],\n`
+    } else {
+      scriptCode += `  ${item.name}: ${item.type === 'number' ? '0' : item.type === 'switch' ? 'false' : '""'},\n`
+    }
+  })
+  
+  scriptCode += `})
+
+// 验证规则
+const rules = reactive<FormRules>({\n`
+  
+  // 添加验证规则
+  selectedItems.forEach(item => {
+    if (item.required || item.rule) {
+      scriptCode += `  ${item.name}: [\n`
+      
+      if (item.required) {
+        scriptCode += `    { required: true, message: '${item.type === 'select' || item.type === 'radio' || item.type === 'checkbox' ? '请选择' : '请输入'}${item.description}', trigger: '${item.type === 'select' || item.type === 'radio' || item.type === 'checkbox' ? 'change' : 'blur'}' },\n`
+      }
+      
+      if (item.rule === 'email') {
+        scriptCode += `    { type: 'email', message: '请输入正确的邮箱地址', trigger: 'blur' },\n`
+      } else if (item.rule === 'phone') {
+        scriptCode += `    { pattern: /^1[3-9]\\d{9}$/, message: '请输入正确的手机号', trigger: 'blur' },\n`
+      } else if (item.rule === 'number') {
+        scriptCode += `    { type: 'number', message: '请输入数字', trigger: 'blur' },\n`
+      }
+      
+      scriptCode += `  ],\n`
+    }
+  })
+  
+  scriptCode += `})
+
+// 打开弹窗
+const openDialog = (title: string, data?: any) => {
+  ${state.dialogConfig.titleVar}.value = title
+  if (data) {
+    Object.assign(formData, data)
+  }
+  ${state.dialogConfig.visibleVar}.value = true
+}
+
+// 关闭弹窗
+const handleDialogClose = () => {
+  formRef.value?.resetFields()
+  ${state.dialogConfig.visibleVar}.value = false
+}
+
+// 提交表单
+const handleSubmit = () => {
+  formRef.value?.validate((valid) => {
+    if (valid) {
+      // 提交逻辑
+      console.log('表单数据:', formData)
+      handleDialogClose()
+    }
+  })
+}
+</` + `script>`
+  
+  // 生成样式代码
+  const styleCode = `<style scoped>
+.dialog-footer {
+  display: flex;
+  justify-content: flex-end;
+}
+</style>`
+  
+  state.generatedCode = {
+    template: templateCode,
+    script: scriptCode,
+    style: styleCode
+  }
+  
+  state.codePreviewVisible = true
+}
+
+// 下载代码
+const downloadCode = () => {
+  const content = `<template>
+${state.generatedCode.template}
+</template>
+
+${state.generatedCode.script}
+
+${state.generatedCode.style}`
+  
+  const blob = new Blob([content], { type: 'text/plain' })
+  const url = URL.createObjectURL(blob)
+  const link = document.createElement('a')
+  link.href = url
+  link.download = 'DialogComponent.vue'
+  document.body.appendChild(link)
+  link.click()
+  document.body.removeChild(link)
+  URL.revokeObjectURL(url)
+  
+  ElMessage.success('代码下载成功')
+}
+
+onMounted(() => {
+  // 初始化加载一些示例数据
+  onChange('')
+})
+</script>
+
+<style scoped lang="scss">
+.layout {
+  position: relative;
+  overflow: hidden;
+  padding: 0px 8px 8px 8px;
+  display: flex;
+  flex-direction: column;
+}
+
+pre {
+  background: #f5f5f5;
+  padding: 10px;
+  border-radius: 4px;
+  overflow: auto;
+  max-height: 60vh;
+}
+
+.mt8 {
+  margin-top: 8px;
+}
+</style>

+ 55 - 8
admin.ui.plus-master/src/views/example/codeGeneration/index.vue

@@ -464,7 +464,7 @@ const onsubmit=()=>{
           </el-form>
           
           <hr>
-          
+
           `
     }
 if(selBtn.length > 0) {
@@ -498,11 +498,12 @@ if(selBtn.length > 0) {
   if(tabVal.length>0){
     indexCode=indexCode+`\n<!--表格-->
       <el-col  :xs="24" >
-        <el-card style="height: 70vh" class="my-fill mt8" shadow="hover">`
+        <el-card style="height: 70vh" class="my-fill mt8" shadow="hover">
+        <el-table v-loading="state.loading" stripe :data="state.tableModel" row-key="id" style="width: 100%">`
     if(selection){
       indexCode=indexCode+`\n<el-table-column type="selection" width="50"></el-table-column>`
     }
-    indexCode=indexCode+`\n<el-table v-loading="state.loading" stripe :data="state.tableModel" row-key="id" style="width: 100%">
+    indexCode=indexCode+`\n
         <el-table-column v-for="column in state.dynamicColumns" :key="column.prop" :prop="column.prop" :label="column.label"  >
         </el-table-column>`
     if(tabBtn.length>0){
@@ -525,8 +526,8 @@ if(selBtn.length > 0) {
     if(state.isPage){
       indexCode=indexCode+`\n<div class="my-flex my-flex-end" style="margin-top: 20px">
             <el-pagination
-              v-model:currentPage="state.pageInput.CurrentPage"
-              v-model:page-size="state.pageInput.PageSize"
+              v-model:currentPage="pageState.pageInput.CurrentPage"
+              v-model:page-size="pageState.pageInput.PageSize"
               :total="state.total"
               :page-sizes="[10, 15, 20, 50, 100]"
               small
@@ -546,9 +547,17 @@ if(selBtn.length > 0) {
   <script setup lang="ts">
   import {onBeforeMount, onMounted, reactive, ref, watch} from "vue";
   import eventBus from "/@/utils/mitt";
-  import {Api} from "/@/api/code/api";`
+  import {Api} from "/@/api/code/api";
+  import { useDynamicPageSize } from "/@/composables/useDynamicPageSize";
+
+  // 使用组合式函数获取分页状态
+const pageState = useDynamicPageSize(10, 15);`
+
+
   if(state.isPage&&tabVal.length>0){
-    indexCode=indexCode+`\nimport { pageInput,${tabVal[0].belong} } from "/@/api/code/dto";`
+    indexCode=indexCode+`\nimport { ${tabVal[0].belong} } from "/@/api/code/dto";
+    import type { pageInput } from "/@/api/code/dto"
+    `
   }else if(tabVal.length>0){
     indexCode=indexCode+`\nimport { ${tabVal[0].belong} } from "/@/api/code/dto";`
   }
@@ -590,6 +599,8 @@ if(selBtn.length > 0) {
   }
   indexCode=indexCode+`\n})
   onMounted(() => {
+    // 初始化分页大小
+    Data.pageInput.pageSize = pageState.pageInput.pageSize; 
     init()
     eventBus.off('refreshView')
     eventBus.on('refreshView', async () => {
@@ -644,7 +655,43 @@ if(selBtn.length > 0) {
       const ${tabBtn[i].method}=(row)=>{}`
     }
   }
-  indexCode=indexCode+`\n</`+`script>`+`\n<style scoped lang="scss">
+  indexCode=indexCode+`\n
+  /**
+* 页条变化
+* @param val
+*/
+const onSizeChange = (val: number) => {
+  Data.pageInput.pageSize = val
+  //需按照页面对象修改Data
+  init()
+}
+
+/**
+ * 页数 变化
+ * @param val
+ */
+const onCurrentChange = (val: number) => {
+  Data.pageInput.currentPage = val
+  //需按照页面对象修改Data
+  init()
+}
+  </`+`script>`+`\n<style scoped lang="scss">
+  .el-input,
+.el-select {
+  width: 240px;
+}
+
+/* 输入框标签固定四个字符宽度 */
+::v-deep .el-form-item__label {
+  // 字体大小14,5个字符,12px右间距
+  width: 14*5px+12px;
+  justify-content: start;
+}
+
+/* 数据表头 设置灰色样式 */
+::v-deep .el-table th.el-table__cell {
+  background-color: #F6F6F6;
+}
   </style>`
   //console.log(indexCode)
   getCodeFile('api.ts',apiCode)