Browse Source

时间格式化

rkljw 1 week ago
parent
commit
ea51541409
2 changed files with 1079 additions and 1041 deletions
  1. 1072 1026
      pages/index_form.vue
  2. 7 15
      plugins/element-plus.js

+ 1072 - 1026
pages/index_form.vue

@@ -1,1026 +1,1072 @@
-<template>
-    <main class="index_main">
-        <HomePageHead></HomePageHead>
-        <HomePageNavigation></HomePageNavigation>
-
-        <el-skeleton v-if="pageLoading" :rows="24" :animated="true" style="margin: 20px;">
-          <template #template>
-            <div class="custom-skeleton-multi">
-              <span
-                v-for="(item, idx) in skeletonChars"
-                :key="idx"
-                class="custom-skeleton-char"
-                :style="{
-                  top: item.top + '%',
-                  left: item.left + '%',
-                  fontSize: item.fontSize + 'px',
-                  opacity: item.opacity,
-                  transform: `rotate(${item.rotate}deg)`
-                }"
-              >政讯通</span>
-            </div>
-          </template>
-        </el-skeleton>
-        <el-form v-else :model="formData" :rules="rules_js" ref="formRef" label-width="120px" class="form_box">
-            <el-form-item 
-                v-for="(per_obj,per_index) in table_head.value" 
-                :key="per_index"
-                :prop="getFieldName(per_obj)"
-                :label="per_obj.title + ':'"
-                :required="per_obj.is_check === 1"
-            >
-                <!-- 文本文字1 -->
-                <el-input 
-                    v-if="checkFieldType(per_obj, 1)"    
-                    v-model="formData[getFieldName(per_obj)]" 
-                    :placeholder="`请输入${per_obj.title}`"
-                />
-                
-                <!-- 多行textarea 2-->
-                <el-input
-                    v-if="checkFieldType(per_obj, 2)"
-                    v-model="formData[getFieldName(per_obj)]" 
-                    type="textarea"
-                    :autosize="{ minRows: 2, maxRows: 4 }"
-                    :placeholder="`请输入${per_obj.title}`"
-                />
-                
-                <!-- 单选按钮 3 -->
-                <el-radio-group 
-                    v-if="checkFieldType(per_obj, 3)" 
-                    v-model="formData[getFieldName(per_obj)]">
-                    <el-radio 
-                        v-for="per_3_obj in radio_arr_fun(per_obj.option_value)" 
-                        :key="`${getFieldName(per_obj)}_${per_3_obj[1]}`"
-                        :label="per_3_obj[1]">
-                        {{ per_3_obj[0] }}
-                    </el-radio>
-                </el-radio-group>
-                
-                <!-- 下拉选择 4 --> 
-                <el-select 
-                    v-if="checkFieldType(per_obj, 4)"
-                    placeholder="请选择"
-                    v-model="formData[getFieldName(per_obj)]" 
-                    style="width: 100%"
-                >
-                    <el-option
-                        v-for="per_4_obj in select_arr_fun(per_obj.option_value)"
-                        :key="`${getFieldName(per_obj)}_${per_4_obj.value}`"
-                        :label="per_4_obj.label"
-                        :value="per_4_obj.value">
-                    </el-option>
-                </el-select>
-                
-                <!-- 复选框5 -->
-                <el-checkbox-group 
-                    v-if="checkFieldType(per_obj, 5)"    
-                    v-model="formData[getFieldName(per_obj)]" 
-                    @change="(value) => handleCheckboxChange(getFieldName(per_obj), value)"
-                > 
-                    <el-checkbox 
-                        v-for="per_5_obj in checkbox_arr_fun(per_obj.option_value)"
-                        :key="`${getFieldName(per_obj)}_${per_5_obj.value}`"
-                        :label="per_5_obj.value">
-                        {{ per_5_obj.label }}
-                    </el-checkbox>
-                </el-checkbox-group>
-                
-                <!-- 日期选择器 6 -->
-                <el-date-picker
-                    v-if="checkFieldType(per_obj, 6)"    
-                    v-model="formData[getFieldName(per_obj)]" 
-                    type="date"
-                    value-format="YYYY-MM-DD"
-                    format="YYYY-MM-DD"
-                    placeholder="选择日期"
-                    style="width: 100%">
-                </el-date-picker>
-                <!-- 单文件上传 7 (新) -->
-                <el-upload
-                    v-if="checkFieldType(per_obj, 7)"
-                    :ref="(el) => uploadRefs[getFieldName(per_obj)] = el"
-                    :action="`${$webUrl}/public/uploadFile`" 
-                    :limit="1"
-                    :on-exceed="(files) => handleExceed(files, getFieldName(per_obj))"
-                    :on-success="(res, file) => handleFileSuccess(res, file, getFieldName(per_obj))"
-                    :on-remove="() => handleFileRemove(getFieldName(per_obj))"
-                    :file-list="fileLists[getFieldName(per_obj)] || []"
-                >
-                    <el-button type="primary">点击上传文件</el-button>
-                    <template #tip>
-                        <div class="el-upload__tip">
-                            只能上传一个文件,新文件将覆盖旧文件。
-                        </div>
-                    </template>
-                </el-upload>
-                <!-- img上传 8 -->
-                <el-upload
-                    v-if="checkFieldType(per_obj, 8)"
-                    class="avatar-uploader"
-                    :action="`${$webUrl}/public/uploadFile`" 
-                    :show-file-list="false"
-                    :on-success="(res) => handleAvatarSuccess(res, getFieldName(per_obj))"
-                    :before-upload="beforeAvatarUpload"
-                >
-                    <img v-if="formData[getFieldName(per_obj)]" :src="formData[getFieldName(per_obj)]" class="avatar" >
-                    <div v-else class="avatar-uploader-placeholder">
-                        <img src="http://img.bjzxtw.org.cn/master/image/noImage.png" class="avatar-placeholder-img" alt="上传头像">
-                        <span class="upload-tip">点击上传</span>
-                    </div>
-                </el-upload>
-            </el-form-item>
-            
-            <!-- 验证码 -->
-            <el-form-item v-if="showCaptcha" prop="code" label="验证码:">
-                <div class="captcha-wrapper">
-                    <el-input v-model="formData.code" placeholder="请输入验证码" @keyup.enter="submitForm"></el-input>
-                    <img v-if="captchaImage" :src="captchaImage" @click="refreshCaptcha" alt="验证码" class="captcha-img" title="点击刷新">
-                </div>
-            </el-form-item>
-
-            <el-form-item class="form-actions">
-                <el-button type="primary" @click="submitForm" :loading="submitLoading">提交</el-button>
-                <el-button @click="resetForm">重置</el-button>
-            </el-form-item>
-        </el-form>
-        <HomeFoot></HomeFoot>
-    </main>
-    <el-dialog v-model="dialogVisible" title="提示" width="300px" :close-on-click-modal="false" :show-close="false" align-center>
-      <div style="text-align:center;">表单提交成功!</div>
-      <template #footer>
-        <div class="dialog-footer-center">
-          <el-button type="primary" @click="onDialogConfirm" class="dialog-confirm-btn">确认</el-button>
-        </div>
-      </template>
-    </el-dialog>
-</template>
-
-<style scoped> 
-@charset "utf-8";
-* {
-    margin: 0;
-    padding: 0;
-    font-family: "微软雅黑", "microsoft yahei";
-}
-
-ul,
-ol {
-    list-style: none;
-}
-
-a:active {
-    text-decoration: none;
-}
-
-a:hover {
-    text-decoration: none;
-}
-
-a:visited {
-    text-decoration: none;
-}
-
-a:link {
-    text-decoration: none;
-}
-
-a:focus {
-    text-decoration: none;
-}
-
-body {
-    position: relative;
-}
-
-.clearfix {
-    overflow: hidden;
-}
-
-.clearfix_2::after {
-    content: '';
-    display: block;
-    height: 0;
-    visibility: hidden;
-    clear: both;
-}
-
-.hiddenColor {
-    visibility: hidden;
-}
-
-.hand {
-    cursor: pointer;
-}
-
-.aTag_parent {
-    position: relative;
-}
-
-.aTag_parent>a,
-.aTag {
-    display: block;
-    width: 100%;
-    height: 100%;
-    position: absolute;
-    z-index: 99;
-    border: 0px;
-    top: 0px;
-    left: 0px;
-    background: rgba(0, 0, 0, 0);
-}
-
-.dot1 {
-    display: block;
-    word-break: keep-all;
-    white-space: nowrap;
-    overflow: hidden;
-    text-overflow: ellipsis;
-}
-
-.dot2 {
-    overflow: hidden;
-    display: -webkit-box;
-    -webkit-box-orient: vertical;
-    -webkit-line-clamp: 2;
-}
-.dot3{
-    overflow: hidden;
-    display: -webkit-box;
-    -webkit-box-orient: vertical;
-    -webkit-line-clamp: 3;
-}
-
-input,
-img {
-    border: none;
-}
-
-.cover100 img {
-    display: block;
-    width: 100%;
-    height: 100%;
-    object-fit: cover;
-}
-
-.back100 {
-    background-size: 100% 100%;
-    background-repeat: no-repeat;
-}
-
-article,
-aside,
-footer,
-header,
-time,
-video,
-main,
-nav,
-h4,
-h3,
-section {
-    display: block;
-}
-
-.index_main {
-    margin: 0 auto;
-}
-
-.slow_6 {
-    -webkit-transition: all .6s;
-    -moz-transition: all .6s;
-    -ms-transition: all .6s;
-    -o-transition: all .6s;
-    transition: all .6s;
-}
-.form_box {
-    width: 1200px;
-    margin: 20px auto;
-    border: dashed 1px #000;
-    padding: 20px;
-}
-   
-.form_box :deep(.avatar-uploader) {
-    border: 1px dashed var(--el-border-color);
-    border-radius: 6px;
-    cursor: pointer;
-    position: relative;
-    overflow: hidden;
-    width: 178px;
-    height: 178px;
-}
-
-.form_box :deep(.avatar-uploader:hover) {
-    border-color: var(--el-color-primary);
-}
-
-.form_box :deep(.avatar-uploader .avatar) {
-    width: 100%;
-    height: 100%;
-    display: block;
-}
-
-.form_box :deep(.avatar-uploader .el-upload) {
-    width: 100%;
-    height: 100%;
-}
-
-.form_box :deep(.el-button--primary) {
-    padding: 0 11px;
-}
-
-@media screen and (min-width:1200px) {
-    /*pc_1440*/
-    @media screen and (max-width:1440px) {
-        /*1200*/
-    }
-
-    .pc_none {
-        display: none;
-    }
-}
-
-@media screen and (max-width:599px) {}
-
-@media screen and (max-width:320px) {}
-
-.form_box .el-form-item {
-    margin-bottom: 20px!important;
-}
-
-.avatar-uploader-placeholder {
-    display: flex;
-    flex-direction: column;
-    justify-content: center;
-    align-items: center;
-    width: 100%;
-    height: 100%;
-}
-
-.avatar-placeholder-img {
-    width: 50px;
-    height: 50px;
-    opacity: 0.5;
-}
-
-.upload-tip {
-    margin-top: 8px;
-    color: #8c939d;
-    font-size: 12px;
-}
-
-.form-actions :deep(.el-form-item__content) {
-    justify-content: center;
-}
-
-.form-actions .el-button + .el-button {
-    margin-left: 20px;
-    padding: 0 11px;
-}
-
-.captcha-wrapper {
-    display: flex;
-    align-items: center;
-    width: 100%;
-}
-
-.captcha-img {
-    margin-left: 10px;
-    cursor: pointer;
-    height: 32px; /* 与el-input默认高度对齐 */
-    border-radius: 4px;
-}
-
-.form_box :deep(.el-checkbox) {
-    margin-right: 20px;
-}
-
-.form_box :deep(.el-radio) {
-    margin-right: 20px;
-}
-
-/* 弹窗footer按钮居中 */
-.dialog-footer-center {
-  display: flex;
-  justify-content: center;
-  align-items: center;
-}
-.dialog-confirm-btn {
-  padding: 0 32px;
-}
-
-.custom-skeleton-multi {
-  position: relative;
-  width: 100%;
-  height: 700px;
-  background: #f5f6fa;
-  border-radius: 8px;
-  overflow: hidden;
-}
-.custom-skeleton-char {
-  position: absolute;
-  color: #e5e6eb;
-  font-weight: bold;
-  letter-spacing: 10px;
-  user-select: none;
-  pointer-events: none;
-  transition: all 0.3s;
-}
-</style>
-
-<script setup>
-//页面是否已经加载完毕
-const pageLoading = ref(true)
-const submitLoading = ref(false)
-const showCaptcha = ref(false)
-const captchaImage = ref('')
-const captchaId = ref('')
-const dialogVisible = ref(false)
-
-//1.加载页面必备组件 start---------------------------------------->
-import { ref, onMounted, reactive, nextTick, onBeforeUpdate } from 'vue';
-import { useSeoMeta } from '#imports';
-
-import { ElForm, ElFormItem, ElInput, ElRadioGroup, ElRadio,
-         ElCheckboxGroup, ElCheckbox, ElUpload, ElMessage,
-         ElSelect, ElOption, ElDatePicker, ElButton, genFileId } from 'element-plus'
-
-const { $webUrl, $CwebUrl } = useNuxtApp();
-
-// 表单引用
-const formRef = ref(null)
-
-// 上传组件引用
-const uploadRefs = ref({});
-const fileLists = ref({});
-
-onBeforeUpdate(() => {
-  uploadRefs.value = {};
-});
-
-let adImg = ref({}) 
-//广告1               
-let url = `${$webUrl}/web/getWebsiteAdvertisement?ad_tag=tsbb_index_1`
-const responseAd1 = await fetch(url, {
-    headers: {
-        'Content-Type': 'application/json',
-        'Userurl': $CwebUrl,
-        'Origin': $CwebUrl
-    }
-});
-const resultAd1 = await responseAd1.json();
-adImg.value = resultAd1.data[0];
- 
-let adImg_2 = ref({}) 
-//广告_2
-let url_2 = `${$webUrl}/web/getWebsiteAdvertisement?ad_tag=tsbb_index_2`
-const responseAd_2 = await fetch(url_2, {
-    headers: {
-        'Content-Type': 'application/json',
-        'Userurl': $CwebUrl,
-        'Origin': $CwebUrl
-    }
-});
-const resultAd_2 = await responseAd_2.json();
-adImg_2.value = resultAd_2.data[0];
-
-// 动态验证规则
-const rules_js = ref({})
-
-const get_from_data_1 = reactive({
-    value:{}
-});
-
-const chinese_calendar = reactive({});
- 
-//列表头
-const table_head = reactive({
-    value:[]
-});
-
-//列表内容
-const table_body = reactive({
-    value:[]
-});
-
-// 表单数据 - 使用ref而不是reactive来避免响应式问题
-const formData = ref({})
-const route = useRoute()
-
-// 从路由获取 table_id,如果不存在则使用默认值
-const table_id = ref(route.query.table_id || 59)
-
-// 得到id
-const recive_id = reactive({
-    value:route.query.id || route.params.id
-})
-
-// 工具函数定义
-function getFieldName(field) {
-    if (field.field) return field.field;
-    const possibleFieldNames = ['name', 'field_name', 'key', 'id'];
-    for (const name of possibleFieldNames) {
-        if (field[name]) return field[name];
-    }
-    return undefined;
-}
-
-// 检查字段类型的函数,支持数组格式
-function checkFieldType(field, type) {
-    if (!field.field_type) return false;
-    if (Array.isArray(field.field_type)) {
-        return field.field_type.map(Number).includes(Number(type));
-    }
-    return Number(field.field_type) === Number(type);
-}
-
-// 检查是否为数组类型字段(field_type为5或包含5的数组)
-function isArrayTypeField(field) {
-    return checkFieldType(field, 5);
-}
-
-// 生成动态验证规则
-function generateValidationRules() {
-    const rules = {}
-    
-    table_head.value.forEach((field, index) => {
-        const fieldRules = []
-        const fieldName = getFieldName(field)
-        
-        // 必填验证
-        if (field.is_check === 1) {
-            fieldRules.push({
-                required: true,
-                message: `${field.title}不能为空`,
-                trigger: ['blur', 'change']
-            })
-        }
-        
-        // 正则验证
-        if (field.regular && field.regular.trim()) {
-            try {
-                const regex = parseRegExp(field.regular)
-                fieldRules.push({
-                    validator: (rule, value, callback) => {
-                        if (value && !regex.test(value)) {
-                            callback(new Error(`${field.title}格式不正确`))
-                        } else {
-                            callback()
-                        }
-                    },
-                    trigger: ['blur', 'change']
-                })
-            } catch (error) {
-                console.error(`正则表达式错误: ${field.regular}`, error)
-            }
-        }
-        
-        if (fieldRules.length > 0 && fieldName) {
-            rules[fieldName] = fieldRules
-        }
-    })
-    
-    // 添加验证码规则
-    if (showCaptcha.value) {
-        rules['code'] = [
-            { required: true, message: '验证码不能为空', trigger: 'blur' }
-        ]
-    }
-
-    rules_js.value = rules
-}
-
-// 刷新验证码
-async function refreshCaptcha() {
-    try {
-        // 拼接 GET 参数
-        const params = new URLSearchParams({ table_id: table_id.value });
-        const url = `${$webUrl}/form/getWebGlobalTableFieldList?${params.toString()}`;
-        
-        const response = await fetch(url, {
-            method: 'GET',
-            headers: {
-                'Content-Type': 'application/json',
-                'Userurl': $CwebUrl,
-                'Origin': $CwebUrl
-            }
-        });
-        const get_from_data = await response.json();
-
-        // 只处理验证码相关的数据
-        if (get_from_data.data?.table?.is_code === 1 && get_from_data.data?.code?.img) {
-            showCaptcha.value = true
-            captchaId.value = get_from_data.data.code.code_uniqid
-            // 确保base64字符串包含正确的前缀
-            if (get_from_data.data.code.img.startsWith('data:image')) {
-                captchaImage.value = get_from_data.data.code.img
-            } else {
-                captchaImage.value = 'data:image/png;base64,' + get_from_data.data.code.img
-            }
-            // 清空验证码输入框
-            formData.value.code = ''
-        } else {
-            showCaptcha.value = false
-            captchaImage.value = ''
-            captchaId.value = ''
-        }
-    } catch (error) {
-        console.error('刷新验证码失败:', error);
-        ElMessage.error('刷新验证码失败,请重试');
-    }
-}
-
-// 获取form所有数据
-async function get_from_data_fun() {
-    pageLoading.value = true
-    try {
-        // 拼接 GET 参数
-        const params = new URLSearchParams({ table_id: table_id.value });
-        const url = `${$webUrl}/form/getWebGlobalTableFieldList?${params.toString()}`;
-        
-        const response = await fetch(url, {
-            method: 'GET',
-            headers: {
-                'Content-Type': 'application/json',
-                'Userurl': $CwebUrl,
-                'Origin': $CwebUrl
-            }
-        });
-        const get_from_data = await response.json();
-
-        // 检查是否需要显示验证码(仅在初始化时)
-        if (get_from_data.data?.table?.is_code === 1 && get_from_data.data?.code?.img) {
-            showCaptcha.value = true
-            captchaId.value = get_from_data.data.code.code_uniqid
-            // 确保base64字符串包含正确的前缀
-            if (get_from_data.data.code.img.startsWith('data:image')) {
-                captchaImage.value = get_from_data.data.code.img
-            } else {
-                captchaImage.value = 'data:image/png;base64,' + get_from_data.data.code.img
-            }
-        } else {
-            showCaptcha.value = false
-            captchaImage.value = ''
-            captchaId.value = ''
-        }
-
-        // 赋值表头和表体
-        table_head.value = get_from_data.data?.fields || [];
-        table_body.value = get_from_data.data?.table || [];
-        get_from_data_1.value = get_from_data;
-
-        // 统一 field_type 为数字或数字数组
-        table_head.value.forEach(field => {
-            if (typeof field.field_type === 'string') {
-                if (field.field_type.includes(',')) {
-                    field.field_type = field.field_type.split(',').map(Number);
-                } else {
-                    field.field_type = Number(field.field_type);
-                }
-            }
-        });
-
-        // 如果API返回的数据为空,使用默认数据
-        if (table_head.value.length === 0) {
-            table_head.value = [
-                {
-                    field: 'name',
-                    title: '姓名',
-                    field_type: 1,
-                    is_check: 1
-                },
-                {
-                    field: 'email',
-                    title: '邮箱',
-                    field_type: 1,
-                    is_check: 1
-                },
-                {
-                    field: 'hobbies',
-                    title: '爱好',
-                    field_type: [5],
-                    is_check: 0,
-                    option_value: {1: "阅读", 2: "运动", 3: "音乐", 4: "旅游"}
-                }
-            ]
-        }
-
-        // 详细检查每个字段的结构
-        table_head.value.forEach((field, index) => {
-            if (field.option_value) {
-            }
-        })
-
-        // 初始化表单数据
-        table_head.value.forEach(field => {
-            const fieldName = getFieldName(field)
-            if (!fieldName) {
-                console.warn(`字段 ${field.title} 无法确定字段名,跳过初始化`)
-                return
-            }
-            
-            // 根据字段类型初始化不同的默认值
-            if (isArrayTypeField(field)) {
-                // 数组类型字段(field_type为5或包含5的数组)初始化为空数组
-                formData.value[fieldName] = []
-            } else if (checkFieldType(field, 7) || checkFieldType(field, 8)) {
-                formData.value[fieldName] = ''
-                fileLists.value[fieldName] = []
-            }
-             else {
-                // 其他类型初始化为空字符串
-                formData.value[fieldName] = ''
-            }
-        })
-
-        // 单独初始化验证码字段
-        if (showCaptcha.value) {
-            formData.value.code = ''
-        }
-        
-        // 生成验证规则
-        generateValidationRules()
-        pageLoading.value = false
-
-    } catch (error) {
-        console.error('请求失败:', error);
-        
-        // 使用默认数据
-        table_head.value = [
-            {
-                field: 'name',
-                title: '姓名',
-                field_type: 1,
-                is_check: 1
-            },
-            {
-                field: 'email',
-                title: '邮箱',
-                field_type: 1,
-                is_check: 1
-            },
-            {
-                field: 'hobbies',
-                title: '爱好',
-                field_type: [5],
-                is_check: 0,
-                option_value: {1: "阅读", 2: "运动", 3: "音乐", 4: "旅游"}
-            }
-        ]
-        
-        // 初始化默认数据
-        table_head.value.forEach(field => {
-            const fieldName = getFieldName(field)
-            if (isArrayTypeField(field)) {
-                formData.value[fieldName] = []
-            } else if (checkFieldType(field, 7) || checkFieldType(field, 8)) {
-                formData.value[fieldName] = ''
-                fileLists.value[fieldName] = []
-            }
-             else {
-                formData.value[fieldName] = ''
-            }
-        })
-        
-        // 单独初始化验证码字段
-        if (showCaptcha.value) {
-            formData.value.code = ''
-        }
-
-        generateValidationRules()
-        pageLoading.value = false
-        ElMessage.warning('API请求失败,使用默认数据')
-    }
-}
-
-// 提交表单
-async function submitForm() {
-    if (!formRef.value) {
-        ElMessage.error('表单引用不存在')
-        return
-    }
-    
-    try {
-        submitLoading.value = true
-        
-        // 手动检查必填字段
-        const requiredFields = table_head.value.filter(field => field.is_check === 1)
-        
-        const missingFields = requiredFields.filter(field => {
-            const fieldName = getFieldName(field)
-            if (!fieldName) {
-                console.warn(`字段 ${field.title} 无法确定字段名`)
-                return true
-            }
-            
-            const value = formData.value[fieldName]
-            const isEmpty = value === '' || value === null || value === undefined || (Array.isArray(value) && value.length === 0)
-            return isEmpty
-        })
-        
-        if (missingFields.length > 0) {
-            ElMessage.error(`请填写必填字段: ${missingFields.map(f => f.title).join(', ')}`)
-            return
-        }
-        
-        // 表单验证 - 使用正确的验证方式
-        await formRef.value.validate(async (valid, fields) => {
-            if (valid) {
-                // 构建提交数据
-                const otherDataPayload = { 'table_id': table_id.value };
-                const dataToSubmit = { ...formData.value };
-
-                if (showCaptcha.value) {
-                    otherDataPayload.code = dataToSubmit.code;
-                    otherDataPayload.code_uniqid = captchaId.value;
-                    delete dataToSubmit.code;
-                }
-
-                const submitData = {
-                    otherData: otherDataPayload,
-                    data: dataToSubmit
-                }
-                
-                // 这里可以调用实际的提交接口
-                const response = await fetch(`${$webUrl}/form/addWebGlobalTableData`, {
-                    method: 'POST',
-                    headers: {
-                        'Content-Type': 'application/json',
-                        'Userurl': $CwebUrl,
-                        'Origin': $CwebUrl
-                    },
-                    body: JSON.stringify(submitData)
-                })
-                const result = await response.json();
-               if(result.code==200){
-                  dialogVisible.value = true
-                  return
-               }else{
-                ElMessage.error(result.message)
-                return
-               }
-                
-            } else {
-                ElMessage.error('请检查表单填写是否正确')
-            }
-        })
-        
-    } catch (error) {
-        console.error('提交失败:', error)
-        ElMessage.error('提交失败,请重试')
-    } finally {
-        submitLoading.value = false
-    }
-}
-
-// 重置表单
-async function resetForm() {
-    await get_from_data_fun();
-    ElMessage.success('表单已重置');
-}
-
-// 下拉选择对象转数组
-function select_arr_fun(option_obj){
-    if (!option_obj || typeof option_obj !== 'object') return []
-    
-    let new_arr = []
-    
-    // 遍历对象,key为value,value为label
-    Object.keys(option_obj).forEach(key => {
-        let the_in_obj = {}
-        the_in_obj.label = option_obj[key]
-        the_in_obj.value = +key  // 转换为数字
-        new_arr.push(the_in_obj)
-    })
-    
-    return new_arr
-}
-
-// 单选按钮对象转数组
-function radio_arr_fun(option_obj) {
-    if (!option_obj || typeof option_obj !== 'object') return []
-    
-    let new_arr = []
-    
-    // 遍历对象,key为value,value为label
-    Object.keys(option_obj).forEach(key => {
-        new_arr.push([option_obj[key], key])  // [label, value] 格式
-    })
-    
-    return new_arr
-}
-
-// 复选框对象转数组
-function checkbox_arr_fun(option_obj) {
-    if (!option_obj || typeof option_obj !== 'object') return []
-    
-    let new_arr = []
-    
-    // 遍历对象,key为value,value为label
-    Object.keys(option_obj).forEach(key => {
-        let the_in_obj = {}
-        the_in_obj.label = option_obj[key]
-        the_in_obj.value = String(key)  // 确保值为字符串类型
-        new_arr.push(the_in_obj)
-    })
-    
-    return new_arr
-}
-
-// 文件上传相关
-// 文件超出限制时的处理
-const handleExceed = (files, fieldName) => {
-  const upload = uploadRefs.value[fieldName];
-  if (upload) {
-    upload.clearFiles();
-    const file = files[0];
-    file.uid = genFileId();
-    upload.handleStart(file);
-    upload.submit();
-  }
-};
-
-// 普通文件上传成功
-const handleFileSuccess = (res, file, fieldName) => {
-    if (res.data && res.data.imgUrl) {
-        formData.value[fieldName] = res.data.imgUrl;
-        if (fileLists.value[fieldName]) {
-             fileLists.value[fieldName] = [{
-                name: file.name,
-                url: res.data.imgUrl
-            }];
-        }
-    }
-};
-
-// 文件移除
-const handleFileRemove = (fieldName) => {
-    formData.value[fieldName] = '';
-    if(fileLists.value[fieldName]) {
-        fileLists.value[fieldName] = [];
-    }
-};
-
-// img上传 8
-const handleAvatarSuccess = (res, fieldName) => {
-    if (res.data && res.data.imgUrl) {
-        formData.value[fieldName] = res.data.imgUrl
-    }
-}
-
-const beforeAvatarUpload = (file) => {
-    const isJPG = file.type === 'image/jpeg'
-    const isPNG = file.type === 'image/png'
-    const isLt2M = file.size / 1024 / 1024 < 2
-
-    if (!isJPG && !isPNG) {
-        ElMessage.error('只能上传 JPG/PNG 格式!')
-        return false
-    }
-    if (!isLt2M) {
-        ElMessage.error('图片大小不能超过 2MB!')
-        return false
-    }
-    return (isJPG || isPNG) && isLt2M
-}
-
-// 页面加载时获取数据
-onMounted(async () => {
-    await get_from_data_fun()
-    
-    // 确保表单引用存在
-    await nextTick()
-    
-    if (formRef.value) {
-    } else {
-    }
-})
-
-// 复选框变化处理
-function handleCheckboxChange(field, value) {
-    // 这里可以根据需要添加更多的逻辑处理
-}
-
-function parseRegExp(str) {
-  if (typeof str === 'string' && str.startsWith('/') && str.lastIndexOf('/') > 0) {
-    const lastSlash = str.lastIndexOf('/');
-    const pattern = str.slice(1, lastSlash);
-    const flags = str.slice(lastSlash + 1);
-    return new RegExp(pattern, flags);
-  }
-  return new RegExp(str);
-}
-
-function onDialogConfirm() {
-  dialogVisible.value = false;
-  resetForm();
-}
-
-const skeletonChars = Array.from({ length: 16 }).map(() => ({
-  top: Math.random() * 80 + 5, // 5%~85%
-  left: Math.random() * 80 + 5, // 5%~85%
-  fontSize: Math.random() * 60 + 60, // 60~120px
-  opacity: Math.random() * 0.4 + 0.3, // 0.3~0.7
-  rotate: Math.random() * 60 - 30 // -30~30deg
-}));
-</script>
+<template>
+    <main class="index_main newsDetail">
+        <HomePageHead></HomePageHead>
+        <HomePageNavigation></HomePageNavigation>
+    
+        <!-- 面包屑导航 -->
+        <div class="breadcrumb">
+            <div class="inner">
+                <span class="location">当前位置:</span>
+                <el-breadcrumb :separator-icon="ArrowRight">
+                    <el-breadcrumb-item>
+                        <NuxtLink to="/">首页</NuxtLink>
+                    </el-breadcrumb-item>
+                   
+                    <el-breadcrumb-item> {{ title }}</el-breadcrumb-item>
+                </el-breadcrumb>
+            </div>
+        </div>
+        <div class="breadcrumb_title">
+            <div>{{ remark }}</div>
+        </div>
+        <el-skeleton v-if="pageLoading" :rows="24" :animated="true" style="margin: 20px;">
+          <template #template>
+            <div class="custom-skeleton-multi">
+              <span
+                v-for="(item, idx) in skeletonChars"
+                :key="idx"
+                class="custom-skeleton-char"
+                :style="{
+                  top: item.top + '%',
+                  left: item.left + '%',
+                  fontSize: item.fontSize + 'px',
+                  opacity: item.opacity,
+                  transform: `rotate(${item.rotate}deg)`
+                }"
+              >政讯通</span>
+            </div>
+          </template>
+        </el-skeleton>
+        <el-form v-else :model="formData" :rules="rules_js" ref="formRef" label-width="120px" class="form_box">
+            <el-form-item 
+                v-for="(per_obj,per_index) in table_head.value" 
+                :key="per_index"
+                :prop="getFieldName(per_obj)"
+                :label="per_obj.title + ':'"
+                :required="per_obj.is_check === 1"
+            >
+                <!-- 文本文字1 -->
+                <el-input 
+                    v-if="checkFieldType(per_obj, 1)"    
+                    v-model="formData[getFieldName(per_obj)]" 
+                    :placeholder="`请输入${per_obj.title}`"
+                />
+                
+                <!-- 多行textarea 2-->
+                <el-input
+                    v-if="checkFieldType(per_obj, 2)"
+                    v-model="formData[getFieldName(per_obj)]" 
+                    type="textarea"
+                    :autosize="{ minRows: 2, maxRows: 4 }"
+                    :placeholder="`请输入${per_obj.title}`"
+                />
+                
+                <!-- 单选按钮 3 -->
+                <el-radio-group 
+                    v-if="checkFieldType(per_obj, 3)" 
+                    v-model="formData[getFieldName(per_obj)]">
+                    <el-radio 
+                        v-for="per_3_obj in radio_arr_fun(per_obj.option_value)" 
+                        :key="`${getFieldName(per_obj)}_${per_3_obj[1]}`"
+                        :label="per_3_obj[1]">
+                        {{ per_3_obj[0] }}
+                    </el-radio>
+                </el-radio-group>
+                
+                <!-- 下拉选择 4 --> 
+                <el-select 
+                    v-if="checkFieldType(per_obj, 4)"
+                    placeholder="请选择"
+                    v-model="formData[getFieldName(per_obj)]" 
+                    style="width: 100%"
+                >
+                    <el-option
+                        v-for="per_4_obj in select_arr_fun(per_obj.option_value)"
+                        :key="`${getFieldName(per_obj)}_${per_4_obj.value}`"
+                        :label="per_4_obj.label"
+                        :value="per_4_obj.value">
+                    </el-option>
+                </el-select>
+                
+                <!-- 复选框5 -->
+                <el-checkbox-group 
+                    v-if="checkFieldType(per_obj, 5)"    
+                    v-model="formData[getFieldName(per_obj)]" 
+                    @change="(value) => handleCheckboxChange(getFieldName(per_obj), value)"
+                > 
+                    <el-checkbox 
+                        v-for="per_5_obj in checkbox_arr_fun(per_obj.option_value)"
+                        :key="`${getFieldName(per_obj)}_${per_5_obj.value}`"
+                        :label="per_5_obj.value">
+                        {{ per_5_obj.label }}
+                    </el-checkbox>
+                </el-checkbox-group>
+                
+                <!-- 日期选择器 6 -->
+                <el-date-picker
+                    v-if="checkFieldType(per_obj, 6)"    
+                    v-model="formData[getFieldName(per_obj)]" 
+                    type="date"
+                    value-format="YYYY-MM-DD"
+                    format="YYYY-MM-DD"
+                    placeholder="选择日期"
+                    style="width: 100%"
+                    :locale="zhCn">
+                </el-date-picker>
+                <!-- 单文件上传 7 (新) -->
+                <el-upload
+                    v-if="checkFieldType(per_obj, 7)"
+                    :ref="(el) => uploadRefs[getFieldName(per_obj)] = el"
+                    :action="`${$webUrl}/public/uploadFile`" 
+                    :limit="1"
+                    :on-exceed="(files) => handleExceed(files, getFieldName(per_obj))"
+                    :on-success="(res, file) => handleFileSuccess(res, file, getFieldName(per_obj))"
+                    :on-remove="() => handleFileRemove(getFieldName(per_obj))"
+                    :file-list="fileLists[getFieldName(per_obj)] || []"
+                >
+                    <el-button type="primary">点击上传文件</el-button>
+                    <template #tip>
+                        <div class="el-upload__tip">
+                            只能上传一个文件,新文件将覆盖旧文件。
+                        </div>
+                    </template>
+                </el-upload>
+                <!-- img上传 8 -->
+                <el-upload
+                    v-if="checkFieldType(per_obj, 8)"
+                    class="avatar-uploader"
+                    :action="`${$webUrl}/public/uploadFile`" 
+                    :show-file-list="false"
+                    :on-success="(res) => handleAvatarSuccess(res, getFieldName(per_obj))"
+                    :before-upload="beforeAvatarUpload"
+                >
+                    <img v-if="formData[getFieldName(per_obj)]" :src="formData[getFieldName(per_obj)]" class="avatar" >
+                    <div v-else class="avatar-uploader-placeholder">
+                        <img src="http://img.bjzxtw.org.cn/master/image/noImage.png" class="avatar-placeholder-img" alt="上传头像">
+                        <span class="upload-tip">点击上传</span>
+                    </div>
+                </el-upload>
+            </el-form-item>
+            
+            <!-- 验证码 -->
+            <el-form-item v-if="showCaptcha" prop="code" label="验证码:">
+                <div class="captcha-wrapper">
+                    <el-input v-model="formData.code" placeholder="请输入验证码" @keyup.enter="submitForm"></el-input>
+                    <img v-if="captchaImage" :src="captchaImage" @click="refreshCaptcha" alt="验证码" class="captcha-img" title="点击刷新">
+                </div>
+            </el-form-item>
+
+            <el-form-item class="form-actions">
+                <el-button type="primary" @click="submitForm" :loading="submitLoading">提交</el-button>
+                <el-button @click="resetForm">重置</el-button>
+            </el-form-item>
+        </el-form>
+        <HomeFoot></HomeFoot>
+    </main>
+    <el-dialog v-model="dialogVisible" title="提示" width="300px" :close-on-click-modal="false" :show-close="false" align-center>
+      <div style="text-align:center;">表单提交成功!</div>
+      <template #footer>
+        <div class="dialog-footer-center">
+          <el-button type="primary" @click="onDialogConfirm" class="dialog-confirm-btn">确认</el-button>
+        </div>
+      </template>
+    </el-dialog>
+</template>
+
+<style scoped> 
+@charset "utf-8";
+* {
+    margin: 0;
+    padding: 0;
+    font-family: "微软雅黑", "microsoft yahei";
+}
+
+ul,
+ol {
+    list-style: none;
+}
+
+a:active {
+    text-decoration: none;
+}
+
+a:hover {
+    text-decoration: none;
+}
+
+a:visited {
+    text-decoration: none;
+}
+
+a:link {
+    text-decoration: none;
+}
+
+a:focus {
+    text-decoration: none;
+}
+
+body {
+    position: relative;
+}
+
+.clearfix {
+    overflow: hidden;
+}
+
+.clearfix_2::after {
+    content: '';
+    display: block;
+    height: 0;
+    visibility: hidden;
+    clear: both;
+}
+
+.hiddenColor {
+    visibility: hidden;
+}
+
+.hand {
+    cursor: pointer;
+}
+
+.aTag_parent {
+    position: relative;
+}
+
+.aTag_parent>a,
+.aTag {
+    display: block;
+    width: 100%;
+    height: 100%;
+    position: absolute;
+    z-index: 99;
+    border: 0px;
+    top: 0px;
+    left: 0px;
+    background: rgba(0, 0, 0, 0);
+}
+
+.dot1 {
+    display: block;
+    word-break: keep-all;
+    white-space: nowrap;
+    overflow: hidden;
+    text-overflow: ellipsis;
+}
+
+.dot2 {
+    overflow: hidden;
+    display: -webkit-box;
+    -webkit-box-orient: vertical;
+    -webkit-line-clamp: 2;
+}
+.dot3{
+    overflow: hidden;
+    display: -webkit-box;
+    -webkit-box-orient: vertical;
+    -webkit-line-clamp: 3;
+}
+
+input,
+img {
+    border: none;
+}
+
+.cover100 img {
+    display: block;
+    width: 100%;
+    height: 100%;
+    object-fit: cover;
+}
+
+.back100 {
+    background-size: 100% 100%;
+    background-repeat: no-repeat;
+}
+
+article,
+aside,
+footer,
+header,
+time,
+video,
+main,
+nav,
+h4,
+h3,
+section {
+    display: block;
+}
+
+.index_main {
+    margin: 0 auto;
+}
+
+.slow_6 {
+    -webkit-transition: all .6s;
+    -moz-transition: all .6s;
+    -ms-transition: all .6s;
+    -o-transition: all .6s;
+    transition: all .6s;
+}
+.form_box {
+    width: 1200px;
+    margin: 0px auto 20px auto;
+    /* border: dashed 1px #000; */
+    padding: 20px;
+}
+   
+.form_box :deep(.avatar-uploader) {
+    border: 1px dashed var(--el-border-color);
+    border-radius: 6px;
+    cursor: pointer;
+    position: relative;
+    overflow: hidden;
+    width: 178px;
+    height: 178px;
+}
+
+.form_box :deep(.avatar-uploader:hover) {
+    border-color: var(--el-color-primary);
+}
+
+.form_box :deep(.avatar-uploader .avatar) {
+    width: 100%;
+    height: 100%;
+    display: block;
+}
+
+.form_box :deep(.avatar-uploader .el-upload) {
+    width: 100%;
+    height: 100%;
+}
+
+.form_box :deep(.el-button--primary) {
+    padding: 0 11px;
+}
+
+@media screen and (min-width:1200px) {
+    /*pc_1440*/
+    @media screen and (max-width:1440px) {
+        /*1200*/
+    }
+
+    .pc_none {
+        display: none;
+    }
+}
+
+@media screen and (max-width:599px) {}
+
+@media screen and (max-width:320px) {}
+
+.form_box .el-form-item {
+    margin-bottom: 20px!important;
+}
+
+.avatar-uploader-placeholder {
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+    align-items: center;
+    width: 100%;
+    height: 100%;
+}
+
+.avatar-placeholder-img {
+    width: 50px;
+    height: 50px;
+    opacity: 0.5;
+}
+
+.upload-tip {
+    margin-top: 8px;
+    color: #8c939d;
+    font-size: 12px;
+}
+
+.form-actions :deep(.el-form-item__content) {
+    justify-content: center;
+}
+
+.form-actions .el-button + .el-button {
+    margin-left: 20px;
+    padding: 0 11px;
+}
+
+.captcha-wrapper {
+    display: flex;
+    align-items: center;
+    width: 100%;
+}
+
+.captcha-img {
+    margin-left: 10px;
+    cursor: pointer;
+    height: 32px; /* 与el-input默认高度对齐 */
+    border-radius: 4px;
+}
+
+.form_box :deep(.el-checkbox) {
+    margin-right: 20px;
+}
+
+.form_box :deep(.el-radio) {
+    margin-right: 20px;
+}
+
+/* 弹窗footer按钮居中 */
+.dialog-footer-center {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+.dialog-confirm-btn {
+  padding: 0 32px;
+}
+
+.custom-skeleton-multi {
+  position: relative;
+  width: 100%;
+  height: 700px;
+  background: #f5f6fa;
+  border-radius: 8px;
+  overflow: hidden;
+}
+.custom-skeleton-char {
+  position: absolute;
+  color: #e5e6eb;
+  font-weight: bold;
+  letter-spacing: 10px;
+  user-select: none;
+  pointer-events: none;
+  transition: all 0.3s;
+}
+.breadcrumb{
+   
+    width: 1200px !important;
+    margin: 20px auto 0px auto !important;
+ 
+}
+.breadcrumb_title{
+    width: 1200px;
+    margin: 20px auto 0px auto;
+    background-color:#0E6EBE ;
+    color:white;
+    line-height: 28px;
+}
+.breadcrumb_title div{
+    font-size: 16px;
+    /* font-weight: bold; */
+    padding: 5px 20px;
+    display: inline-block;
+    vertical-align: middle;
+    letter-spacing: 3px; /* 添加字间距,可以根据需要调整数值 */
+
+}
+</style>
+<style lang="less" scoped>
+            .breadcrumb {
+                width: 100%;
+                height: 22px;
+                margin-top: 40px;
+                font-family: Microsoft YaHei, Microsoft YaHei;
+                font-weight: 400;
+                font-size: 20px;
+                color: #666666;
+                line-height: 23px;
+                text-align: left;
+                font-style: normal;
+                text-transform: none;
+
+                .el-breadcrumb::v-deep {
+                    display: inline-block;
+                    vertical-align: -4px;
+                }
+
+                :deep(.el-breadcrumb__inner a),
+                :deep(.el-breadcrumb__inner.is-link) {
+                    color: #666666;
+                    font-weight: 400;
+                    text-decoration: none;
+                    transition: var(--el-transition-color);
+                }
+
+                span {
+                    font-family: Microsoft YaHei, Microsoft YaHei;
+                    font-weight: 400;
+                    font-size: 20px;
+                    color: #666666;
+                    line-height: 23px;
+                    text-align: left;
+                    font-style: normal;
+                    text-transform: none;
+                }
+
+                span:hover {
+                    color: #666666;
+                }
+
+                .location {
+                    margin-right: 20px;
+                    width: 100px;
+                    height: 22px;
+                    font-family: Microsoft YaHei, Microsoft YaHei;
+                    font-weight: 400;
+                    font-size: 20px;
+                    color: #666666;
+                    line-height: 23px;
+                    text-align: left;
+                    font-style: normal;
+                    text-transform: none;
+                }
+            }
+</style>
+<script setup>
+import { ArrowRight } from '@element-plus/icons-vue'
+//页面是否已经加载完毕
+const pageLoading = ref(true)
+const submitLoading = ref(false)
+const showCaptcha = ref(false)
+const captchaImage = ref('')
+const captchaId = ref('')
+const dialogVisible = ref(false)
+const title = ref('ceshi')
+const remark = ref('nice')
+const seoTitle = ref('')
+const seoKeywords = ref('')
+const seoDescription = ref('')
+//1.加载页面必备组件 start---------------------------------------->
+import { ref, onMounted, reactive, nextTick, onBeforeUpdate } from 'vue';
+import { useSeoMeta } from '#imports';
+
+import {ElBreadcrumb, ElBreadcrumbItem, ElForm, ElFormItem, ElInput, ElRadioGroup, ElRadio,
+         ElCheckboxGroup, ElCheckbox, ElUpload, ElMessage,
+         ElSelect, ElOption, ElDatePicker, ElButton, genFileId,ElDialog } from 'element-plus'
+
+const { $webUrl, $CwebUrl } = useNuxtApp();
+
+// 表单引用
+const formRef = ref(null)
+
+// 上传组件引用
+const uploadRefs = ref({});
+const fileLists = ref({});
+
+onBeforeUpdate(() => {
+  uploadRefs.value = {};
+});
+
+
+// 动态验证规则
+const rules_js = ref({})
+
+const get_from_data_1 = reactive({
+    value:{}
+});
+const get_from_data= reactive({
+    value:{}
+});
+const chinese_calendar = reactive({});
+ 
+//列表头
+const table_head = reactive({
+    value:[]
+});
+
+//列表内容
+const table_body = reactive({
+    value:[]
+});
+
+// 表单数据 - 使用ref而不是reactive来避免响应式问题
+const formData = ref({})
+const route = useRoute()
+
+// 从路由获取 table_id,如果不存在则使用默认值
+const table_id = ref(route.query.table_id || 59)
+
+// 得到id
+const recive_id = reactive({
+    value:route.query.id || route.params.id
+})
+
+// 工具函数定义
+function getFieldName(field) {
+    if (field.field) return field.field;
+    const possibleFieldNames = ['name', 'field_name', 'key', 'id'];
+    for (const name of possibleFieldNames) {
+        if (field[name]) return field[name];
+    }
+    return undefined;
+}
+
+// 检查字段类型的函数,支持数组格式
+function checkFieldType(field, type) {
+    if (!field.field_type) return false;
+    if (Array.isArray(field.field_type)) {
+        return field.field_type.map(Number).includes(Number(type));
+    }
+    return Number(field.field_type) === Number(type);
+}
+
+// 检查是否为数组类型字段(field_type为5或包含5的数组)
+function isArrayTypeField(field) {
+    return checkFieldType(field, 5);
+}
+
+// 生成动态验证规则
+function generateValidationRules() {
+    const rules = {}
+    
+    table_head.value.forEach((field, index) => {
+        const fieldRules = []
+        const fieldName = getFieldName(field)
+        
+        // 必填验证
+        if (field.is_check === 1) {
+            fieldRules.push({
+                required: true,
+                message: `${field.title}不能为空`,
+                trigger: ['blur', 'change']
+            })
+        }
+        
+        // 正则验证
+        if (field.regular && field.regular.trim()) {
+            try {
+                const regex = parseRegExp(field.regular)
+                fieldRules.push({
+                    validator: (rule, value, callback) => {
+                        if (value && !regex.test(value)) {
+                            callback(new Error(`${field.title}格式不正确`))
+                        } else {
+                            callback()
+                        }
+                    },
+                    trigger: ['blur', 'change']
+                })
+            } catch (error) {
+                console.error(`正则表达式错误: ${field.regular}`, error)
+            }
+        }
+        
+        if (fieldRules.length > 0 && fieldName) {
+            rules[fieldName] = fieldRules
+        }
+    })
+    
+    // 添加验证码规则
+    if (showCaptcha.value) {
+        rules['code'] = [
+            { required: true, message: '验证码不能为空', trigger: 'blur' }
+        ]
+    }
+
+    rules_js.value = rules
+}
+
+// 刷新验证码
+async function refreshCaptcha() {
+    try {
+        // 拼接 GET 参数
+        const params = new URLSearchParams({ table_id: table_id.value });
+        const url = `${$webUrl}/form/getWebGlobalTableFieldList?${params.toString()}`;
+        
+        const response = await fetch(url, {
+            method: 'GET',
+            headers: {
+                'Content-Type': 'application/json',
+                'Userurl': $CwebUrl,
+                'Origin': $CwebUrl
+            }
+        });
+        const get_from_data = await response.json();
+
+        // 只处理验证码相关的数据
+        if (get_from_data.data?.table?.is_code === 1 && get_from_data.data?.code?.img) {
+            showCaptcha.value = true
+            captchaId.value = get_from_data.data.code.code_uniqid
+            // 确保base64字符串包含正确的前缀
+            if (get_from_data.data.code.img.startsWith('data:image')) {
+                captchaImage.value = get_from_data.data.code.img
+            } else {
+                captchaImage.value = 'data:image/png;base64,' + get_from_data.data.code.img
+            }
+            // 清空验证码输入框
+            formData.value.code = ''
+        } else {
+            showCaptcha.value = false
+            captchaImage.value = ''
+            captchaId.value = ''
+        }
+    } catch (error) {
+        console.error('刷新验证码失败:', error);
+        ElMessage.error('刷新验证码失败,请重试');
+    }
+}
+useSeoMeta({
+            title:  seoTitle,
+            meta: [
+                { name: 'keywords', content: seoKeywords, tagPriority: 10 },
+                { name: 'description', content: seoDescription, tagPriority: 10 }
+            ]
+});
+async function get_from_data_fun() {
+    pageLoading.value = true
+    try {
+        // 拼接 GET 参数
+        const params = new URLSearchParams({ table_id: table_id.value });
+        const url = `/form/getWebGlobalTableFieldList?${params.toString()}`;
+        console.log("url:",url)
+        const response = await requestDataPromise(url, {
+            method: 'GET',
+            query: {}
+            
+        });
+        const get_from_data = response
+        console.log("返回数据:",get_from_data,response)
+        title.value = get_from_data.data.table.name
+        remark.value = get_from_data.data.table.remark
+        seoTitle.value = response.data.table.name + "_" + response.data.table.website_name + "_" + response.data.table.suffix
+        seoKeywords.value = response.data.table.keywords + "_" + response.data.table.website_name + "_" + response.data.table.suffix
+        seoDescription.value = response.data.table.description + "_" + response.data.table.website_name + "_" + response.data.table.suffix
+       
+        // 检查是否需要显示验证码(仅在初始化时)
+        if (get_from_data.data?.table?.is_code === 1 && get_from_data.data?.code?.img) {
+            showCaptcha.value = true
+            captchaId.value = get_from_data.data.code.code_uniqid
+            // 确保base64字符串包含正确的前缀
+            if (get_from_data.data.code.img.startsWith('data:image')) {
+                captchaImage.value = get_from_data.data.code.img
+            } else {
+                captchaImage.value = 'data:image/png;base64,' + get_from_data.data.code.img
+            }
+        } else {
+            showCaptcha.value = false
+            captchaImage.value = ''
+            captchaId.value = ''
+        }
+
+        // 赋值表头和表体
+        table_head.value = get_from_data.data?.fields || [];
+        table_body.value = get_from_data.data?.table || [];
+        get_from_data_1.value = get_from_data;
+
+        // 统一 field_type 为数字或数字数组
+        table_head.value.forEach(field => {
+            if (typeof field.field_type === 'string') {
+                if (field.field_type.includes(',')) {
+                    field.field_type = field.field_type.split(',').map(Number);
+                } else {
+                    field.field_type = Number(field.field_type);
+                }
+            }
+        });
+
+        // 如果API返回的数据为空,使用默认数据
+        if (table_head.value.length === 0) {
+            table_head.value = []
+        }
+
+        // 详细检查每个字段的结构
+        table_head.value.forEach((field, index) => {
+            if (field.option_value) {
+            }
+        })
+
+        // 初始化表单数据
+        table_head.value.forEach(field => {
+            const fieldName = getFieldName(field)
+            if (!fieldName) {
+                console.warn(`字段 ${field.title} 无法确定字段名,跳过初始化`)
+                return
+            }
+            
+            // 根据字段类型初始化不同的默认值
+            if (isArrayTypeField(field)) {
+                // 数组类型字段(field_type为5或包含5的数组)初始化为空数组
+                formData.value[fieldName] = []
+            } else if (checkFieldType(field, 7) || checkFieldType(field, 8)) {
+                formData.value[fieldName] = ''
+                fileLists.value[fieldName] = []
+            }
+             else {
+                // 其他类型初始化为空字符串
+                formData.value[fieldName] = ''
+            }
+        })
+
+        // 单独初始化验证码字段
+        if (showCaptcha.value) {
+            formData.value.code = ''
+        }
+        
+        // 生成验证规则
+        generateValidationRules()
+        pageLoading.value = false
+
+    } catch (error) {
+        console.error('请求失败:', error);
+        
+        // 使用默认数据
+        table_head.value = []
+        
+        // 初始化默认数据
+        table_head.value.forEach(field => {
+            const fieldName = getFieldName(field)
+            if (isArrayTypeField(field)) {
+                formData.value[fieldName] = []
+            } else if (checkFieldType(field, 7) || checkFieldType(field, 8)) {
+                formData.value[fieldName] = ''
+                fileLists.value[fieldName] = []
+            }
+             else {
+                formData.value[fieldName] = ''
+            }
+        })
+        
+        // 单独初始化验证码字段
+        if (showCaptcha.value) {
+            formData.value.code = ''
+        }
+
+        generateValidationRules()
+        pageLoading.value = false
+        ElMessage.warning('API请求失败,使用默认数据')
+    }
+}
+get_from_data_fun();
+
+// 提交表单
+async function submitForm() {
+    if (!formRef.value) {
+        ElMessage.error('表单引用不存在')
+        return
+    }
+    
+    try {
+        submitLoading.value = true
+        
+        // 手动检查必填字段
+        const requiredFields = table_head.value.filter(field => field.is_check === 1)
+        
+        const missingFields = requiredFields.filter(field => {
+            const fieldName = getFieldName(field)
+            if (!fieldName) {
+                console.warn(`字段 ${field.title} 无法确定字段名`)
+                return true
+            }
+            
+            const value = formData.value[fieldName]
+            const isEmpty = value === '' || value === null || value === undefined || (Array.isArray(value) && value.length === 0)
+            return isEmpty
+        })
+        
+        if (missingFields.length > 0) {
+            ElMessage.error(`请填写必填字段: ${missingFields.map(f => f.title).join(', ')}`)
+            return
+        }
+        
+        // 表单验证 - 使用正确的验证方式
+        await formRef.value.validate(async (valid, fields) => {
+            if (valid) {
+                // 构建提交数据
+                const otherDataPayload = { 'table_id': table_id.value };
+                const dataToSubmit = { ...formData.value };
+
+                if (showCaptcha.value) {
+                    otherDataPayload.code = dataToSubmit.code;
+                    otherDataPayload.code_uniqid = captchaId.value;
+                    delete dataToSubmit.code;
+                }
+
+                const submitData = {
+                    otherData: otherDataPayload,
+                    data: dataToSubmit
+                }
+                
+                // 这里可以调用实际的提交接口
+                const response = await fetch(`${$webUrl}/form/addWebGlobalTableData`, {
+                    method: 'POST',
+                    headers: {
+                        'Content-Type': 'application/json',
+                        'Userurl': $CwebUrl,
+                        'Origin': $CwebUrl
+                    },
+                    body: JSON.stringify(submitData)
+                })
+                const result = await response.json();
+               if(result.code==200){
+                  dialogVisible.value = true
+                  return
+               }else{
+                ElMessage.error(result.message)
+                return
+               }
+                
+            } else {
+                ElMessage.error('请检查表单填写是否正确')
+            }
+        })
+        
+    } catch (error) {
+        console.error('提交失败:', error)
+        ElMessage.error('提交失败,请重试')
+    } finally {
+        submitLoading.value = false
+    }
+}
+
+// 重置表单
+async function resetForm() {
+    await get_from_data_fun();
+    ElMessage.success('表单已重置');
+}
+
+// 下拉选择对象转数组
+function select_arr_fun(option_obj){
+    if (!option_obj || typeof option_obj !== 'object') return []
+    
+    let new_arr = []
+    
+    // 遍历对象,key为value,value为label
+    Object.keys(option_obj).forEach(key => {
+        let the_in_obj = {}
+        the_in_obj.label = option_obj[key]
+        the_in_obj.value = +key  // 转换为数字
+        new_arr.push(the_in_obj)
+    })
+    
+    return new_arr
+}
+
+// 单选按钮对象转数组
+function radio_arr_fun(option_obj) {
+    if (!option_obj || typeof option_obj !== 'object') return []
+    
+    let new_arr = []
+    
+    // 遍历对象,key为value,value为label
+    Object.keys(option_obj).forEach(key => {
+        new_arr.push([option_obj[key], key])  // [label, value] 格式
+    })
+    
+    return new_arr
+}
+
+// 复选框对象转数组
+function checkbox_arr_fun(option_obj) {
+    if (!option_obj || typeof option_obj !== 'object') return []
+    
+    let new_arr = []
+    
+    // 遍历对象,key为value,value为label
+    Object.keys(option_obj).forEach(key => {
+        let the_in_obj = {}
+        the_in_obj.label = option_obj[key]
+        the_in_obj.value = String(key)  // 确保值为字符串类型
+        new_arr.push(the_in_obj)
+    })
+    
+    return new_arr
+}
+
+// 文件上传相关
+// 文件超出限制时的处理
+const handleExceed = (files, fieldName) => {
+  const upload = uploadRefs.value[fieldName];
+  if (upload) {
+    upload.clearFiles();
+    const file = files[0];
+    file.uid = genFileId();
+    upload.handleStart(file);
+    upload.submit();
+  }
+};
+
+// 普通文件上传成功
+const handleFileSuccess = (res, file, fieldName) => {
+    if (res.data && res.data.imgUrl) {
+        formData.value[fieldName] = res.data.imgUrl;
+        if (fileLists.value[fieldName]) {
+             fileLists.value[fieldName] = [{
+                name: file.name,
+                url: res.data.imgUrl
+            }];
+        }
+    }
+};
+
+// 文件移除
+const handleFileRemove = (fieldName) => {
+    formData.value[fieldName] = '';
+    if(fileLists.value[fieldName]) {
+        fileLists.value[fieldName] = [];
+    }
+};
+
+// img上传 8
+const handleAvatarSuccess = (res, fieldName) => {
+    if (res.data && res.data.imgUrl) {
+        formData.value[fieldName] = res.data.imgUrl
+    }
+}
+
+const beforeAvatarUpload = (file) => {
+    const isJPG = file.type === 'image/jpeg'
+    const isPNG = file.type === 'image/png'
+    const isLt2M = file.size / 1024 / 1024 < 2
+
+    if (!isJPG && !isPNG) {
+        ElMessage.error('只能上传 JPG/PNG 格式!')
+        return false
+    }
+    if (!isLt2M) {
+        ElMessage.error('图片大小不能超过 2MB!')
+        return false
+    }
+    return (isJPG || isPNG) && isLt2M
+}
+
+// 页面加载时获取数据
+onMounted(async () => {
+    await get_from_data_fun()
+    
+    // 确保表单引用存在
+    await nextTick()
+    
+    if (formRef.value) {
+    } else {
+    }
+})
+
+// 复选框变化处理
+function handleCheckboxChange(field, value) {
+    // 这里可以根据需要添加更多的逻辑处理
+}
+
+function parseRegExp(str) {
+  if (typeof str === 'string' && str.startsWith('/') && str.lastIndexOf('/') > 0) {
+    const lastSlash = str.lastIndexOf('/');
+    const pattern = str.slice(1, lastSlash);
+    const flags = str.slice(lastSlash + 1);
+    return new RegExp(pattern, flags);
+  }
+  return new RegExp(str);
+}
+
+function onDialogConfirm() {
+  dialogVisible.value = false;
+  resetForm();
+}
+
+const skeletonChars = Array.from({ length: 16 }).map(() => ({
+  top: Math.random() * 80 + 5, // 5%~85%
+  left: Math.random() * 80 + 5, // 5%~85%
+  fontSize: Math.random() * 60 + 60, // 60~120px
+  opacity: Math.random() * 0.4 + 0.3, // 0.3~0.7
+  rotate: Math.random() * 60 - 30 // -30~30deg
+}));
+</script>

+ 7 - 15
plugins/element-plus.js

@@ -1,17 +1,9 @@
-// import { defineNuxtPlugin } from '#app';
-// import ElementPlus from 'element - plus';
-// import 'element - plus/dist/index.css';
-// // 如果安装了图标相关插件,还需导入并注册图标
-// import * as ElementPlusIconsVue from '@element - plus/icons - vue';
+import { defineNuxtPlugin } from '#app'
+import ElementPlus from 'element-plus'
+import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
 
-// export default defineNuxtPlugin((nuxtApp) => {
-//   nuxtApp.vueApp.use(ElementPlus);
-//   // 注册图标
-//   for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
-//     nuxtApp.vueApp.component(key, component);
-//   }
-// });
-
-export default defineNuxtPlugin(() => {
-    
+export default defineNuxtPlugin((nuxtApp) => {
+  nuxtApp.vueApp.use(ElementPlus, {
+    locale: zhCn,
+  })
 })