Просмотр исходного кода

feat(文档模板): 添加富文本编辑器并优化稿纸表单样式

liujt 4 месяцев назад
Родитель
Сommit
3076104f4e

+ 211 - 0
src/components/TinymceEditor/index.vue

@@ -0,0 +1,211 @@
+<!-- 富文本编辑器 -->
+<template>
+  <component v-if="inlineEditor" :is="tagName" :id="elementId" />
+  <textarea v-else :id="elementId"></textarea>
+</template>
+
+<script>
+  import tinymce from 'tinymce/tinymce';
+  import 'tinymce/themes/silver';
+  import 'tinymce/icons/default';
+  import 'tinymce/plugins/code';
+  import 'tinymce/plugins/preview';
+  import 'tinymce/plugins/fullscreen';
+  import 'tinymce/plugins/paste';
+  import 'tinymce/plugins/searchreplace';
+  import 'tinymce/plugins/save';
+  import 'tinymce/plugins/autosave';
+  import 'tinymce/plugins/link';
+  import 'tinymce/plugins/autolink';
+  import 'tinymce/plugins/image';
+  import 'tinymce/plugins/media';
+  import 'tinymce/plugins/table';
+  import 'tinymce/plugins/codesample';
+  import 'tinymce/plugins/lists';
+  import 'tinymce/plugins/advlist';
+  import 'tinymce/plugins/hr';
+  import 'tinymce/plugins/charmap';
+  import 'tinymce/plugins/emoticons';
+  import 'tinymce/plugins/anchor';
+  import 'tinymce/plugins/directionality';
+  import 'tinymce/plugins/pagebreak';
+  import 'tinymce/plugins/quickbars';
+  import 'tinymce/plugins/nonbreaking';
+  import 'tinymce/plugins/visualblocks';
+  import 'tinymce/plugins/visualchars';
+  import 'tinymce/plugins/wordcount';
+  import 'tinymce/plugins/emoticons/js/emojis';
+  import {
+    DEFAULT_CONFIG,
+    DARK_CONFIG,
+    uuid,
+    bindHandlers,
+    openAlert
+  } from './util';
+
+  export default {
+    name: 'TinymceEditor',
+    props: {
+      // 编辑器唯一 id
+      id: String,
+      // v-model
+      value: String,
+      // 编辑器配置
+      init: Object,
+      // 是否内联模式
+      inline: {
+        type: Boolean,
+        default: false
+      },
+      // model events
+      modelEvents: {
+        type: String,
+        default: 'change input undo redo'
+      },
+      // 内联模式标签名
+      tagName: {
+        type: String,
+        default: 'div'
+      },
+      // 是否禁用
+      disabled: Boolean,
+      // 自动跟随框架主题
+      autoTheme: {
+        type: Boolean,
+        default: true
+      },
+      // 是否使用暗黑主题
+      darkTheme: Boolean
+    },
+    data() {
+      return {
+        // 编辑器唯一 id
+        elementId: this.id || uuid('tiny-vue'),
+        // 编辑器实例
+        editorIns: null,
+        // 是否内联模式
+        inlineEditor: this.init?.inline || this.inline
+      };
+    },
+    computed: {
+      // 是否是暗黑模式
+      darkMode() {
+        return this.$store?.state?.theme?.darkMode;
+      }
+    },
+    methods: {
+      /* 更新 value */
+      updateValue(value) {
+        this.$emit('input', value);
+      },
+      /* 修改内容 */
+      setContent(value) {
+        if (
+          this.editorIns &&
+          typeof value === 'string' &&
+          value !== this.editorIns.getContent()
+        ) {
+          this.editorIns.setContent(value);
+        }
+      },
+      /* 渲染编辑器 */
+      render() {
+        const isDark = this.autoTheme ? this.darkMode : this.darkTheme;
+        tinymce.init({
+          ...DEFAULT_CONFIG,
+          ...(isDark ? DARK_CONFIG : {}),
+          ...this.init,
+          selector: `#${this.elementId}`,
+          readonly: this.disabled,
+          inline: this.inlineEditor,
+          setup: (editor) => {
+            this.editorIns = editor;
+            editor.on('init', (e) => {
+              // 回显初始值
+              if (this.value) {
+                this.setContent(this.value);
+              }
+              // v-model
+              editor.on(this.modelEvents, () => {
+                this.updateValue(editor.getContent());
+              });
+              // valid events
+              bindHandlers(e, this.$attrs, editor);
+            });
+            if (typeof this.init?.setup === 'function') {
+              this.init.setup(editor);
+            }
+          }
+        });
+      },
+      /* 销毁编辑器 */
+      destory() {
+        if (tinymce != null && this.editorIns != null) {
+          tinymce.remove(this.editorIns);
+          this.editorIns = null;
+        }
+      },
+      /* 弹出提示框 */
+      alert(option) {
+        openAlert(this.editorIns, option);
+      }
+    },
+    watch: {
+      value(val, prevVal) {
+        if (val !== prevVal) {
+          this.setContent(val);
+        }
+      },
+      disabled(disable) {
+        if (this.editorIns !== null) {
+          if (typeof this.editorIns.mode?.set === 'function') {
+            this.editorIns.mode.set(disable ? 'readonly' : 'design');
+          } else {
+            this.editorIns.setMode(disable ? 'readonly' : 'design');
+          }
+        }
+      },
+      tagName() {
+        this.destory();
+        this.$nextTick(() => {
+          this.render();
+        });
+      },
+      darkMode() {
+        if (this.autoTheme) {
+          this.destory();
+          this.$nextTick(() => {
+            this.render();
+          });
+        }
+      }
+    },
+    mounted() {
+      this.render();
+    },
+    beforeDestroy() {
+      this.destory();
+    },
+    activated() {
+      this.render();
+    },
+    deactivated() {
+      this.destory();
+    }
+  };
+</script>
+
+<style>
+  body .tox-tinymce-aux {
+    z-index: 19990000;
+  }
+
+  textarea[id^='tiny-vue'] {
+    width: 0;
+    height: 0;
+    margin: 0;
+    padding: 0;
+    opacity: 0;
+    box-sizing: border-box;
+  }
+</style>

+ 229 - 0
src/components/TinymceEditor/util.js

@@ -0,0 +1,229 @@
+const BASE_URL = process.env.BASE_URL;
+
+// 默认加载插件
+const PLUGINS = [
+  'code',
+  'preview',
+  'fullscreen',
+  'paste',
+  'searchreplace',
+  'save',
+  'autosave',
+  'link',
+  'autolink',
+  'image',
+  'media',
+  'table',
+  'codesample',
+  'lists',
+  'advlist',
+  'hr',
+  'charmap',
+  'emoticons',
+  'anchor',
+  'directionality',
+  'pagebreak',
+  'quickbars',
+  'nonbreaking',
+  'visualblocks',
+  'visualchars',
+  'wordcount'
+].join(' ');
+
+// 默认工具栏布局
+const TOOLBAR = [
+  'fullscreen',
+  'preview',
+  'code',
+  '|',
+  'undo',
+  'redo',
+  '|',
+  'forecolor',
+  'backcolor',
+  '|',
+  'bold',
+  'italic',
+  'underline',
+  'strikethrough',
+  '|',
+  'alignleft',
+  'aligncenter',
+  'alignright',
+  'alignjustify',
+  '|',
+  'outdent',
+  'indent',
+  '|',
+  'numlist',
+  'bullist',
+  '|',
+  'formatselect',
+  'fontselect',
+  'fontsizeselect',
+  '|',
+  'link',
+  'image',
+  'media',
+  'emoticons',
+  'charmap',
+  'anchor',
+  'pagebreak',
+  'codesample',
+  '|',
+  'ltr',
+  'rtl'
+].join(' ');
+
+// 默认配置
+export const DEFAULT_CONFIG = {
+  height: 300,
+  branding: false,
+  skin_url: BASE_URL + 'tinymce/skins/ui/oxide',
+  content_css: BASE_URL + 'tinymce/skins/content/default/content.min.css',
+  language_url: BASE_URL + 'tinymce/langs/zh_CN.js',
+  language: 'zh-CN',
+  plugins: PLUGINS,
+  toolbar: TOOLBAR,
+  draggable_modal: true,
+  toolbar_mode: 'sliding',
+  quickbars_insert_toolbar: '',
+  images_upload_handler: (blobInfo, success, error) => {
+    if (blobInfo.blob().size / 1024 > 400) {
+      error('大小不能超过 400KB');
+      return;
+    }
+    success('data:image/jpeg;base64,' + blobInfo.base64());
+  },
+  file_picker_types: 'media',
+  file_picker_callback: () => {}
+};
+
+// 暗黑主题配置
+export const DARK_CONFIG = {
+  skin_url: BASE_URL + 'tinymce/skins/ui/oxide-dark',
+  content_css: BASE_URL + 'tinymce/skins/content/dark/content.min.css'
+};
+
+// 支持监听的事件
+export const VALID_EVENTS = [
+  'onActivate',
+  'onAddUndo',
+  'onBeforeAddUndo',
+  'onBeforeExecCommand',
+  'onBeforeGetContent',
+  'onBeforeRenderUI',
+  'onBeforeSetContent',
+  'onBeforePaste',
+  'onBlur',
+  'onChange',
+  'onClearUndos',
+  'onClick',
+  'onContextMenu',
+  'onCopy',
+  'onCut',
+  'onDblclick',
+  'onDeactivate',
+  'onDirty',
+  'onDrag',
+  'onDragDrop',
+  'onDragEnd',
+  'onDragGesture',
+  'onDragOver',
+  'onDrop',
+  'onExecCommand',
+  'onFocus',
+  'onFocusIn',
+  'onFocusOut',
+  'onGetContent',
+  'onHide',
+  'onInit',
+  'onKeyDown',
+  'onKeyPress',
+  'onKeyUp',
+  'onLoadContent',
+  'onMouseDown',
+  'onMouseEnter',
+  'onMouseLeave',
+  'onMouseMove',
+  'onMouseOut',
+  'onMouseOver',
+  'onMouseUp',
+  'onNodeChange',
+  'onObjectResizeStart',
+  'onObjectResized',
+  'onObjectSelected',
+  'onPaste',
+  'onPostProcess',
+  'onPostRender',
+  'onPreProcess',
+  'onProgressState',
+  'onRedo',
+  'onRemove',
+  'onReset',
+  'onSaveContent',
+  'onSelectionChange',
+  'onSetAttrib',
+  'onSetContent',
+  'onShow',
+  'onSubmit',
+  'onUndo',
+  'onVisualAid'
+];
+
+let unique = 0;
+
+/**
+ * 生成编辑器 id
+ */
+export function uuid(prefix) {
+  const time = Date.now();
+  const random = Math.floor(Math.random() * 1000000000);
+  unique++;
+  return prefix + '_' + random + unique + String(time);
+}
+
+/**
+ * 绑定事件
+ */
+export function bindHandlers(initEvent, listeners, editor) {
+  const validEvents = VALID_EVENTS.map((event) => event.toLowerCase());
+  Object.keys(listeners)
+    .filter((key) => validEvents.includes(key.toLowerCase()))
+    .forEach((key) => {
+      const handler = listeners[key];
+      if (typeof handler === 'function') {
+        if (key === 'onInit') {
+          handler(initEvent, editor);
+        } else {
+          editor.on(key.substring(2), (e) => handler(e, editor));
+        }
+      }
+    });
+}
+
+/**
+ * 弹出提示框
+ */
+export function openAlert(editor, option = {}) {
+  editor?.windowManager?.open({
+    title: option.title ?? '提示',
+    body: {
+      type: 'panel',
+      items: [
+        {
+          type: 'htmlpanel',
+          html: `<p>${option.content ?? ''}</p>`
+        }
+      ]
+    },
+    buttons: [
+      {
+        type: 'cancel',
+        name: 'closeButton',
+        text: '确定',
+        primary: true
+      }
+    ]
+  });
+}

+ 9 - 4
src/views/bpm/documents/documentTemplate/components/file-add.vue

@@ -44,20 +44,24 @@
                 <el-tab-pane label="稿纸信息" name="2">
                     <MainBodyTemplate></MainBodyTemplate>
                 </el-tab-pane>
-                <el-tab-pane label="正文" name="3"></el-tab-pane>
+                <el-tab-pane label="正文" name="3">
+                     <tinymce-editor v-model="formData.content" :init="{ height: 525 }" />
+                </el-tab-pane>
             </el-tabs>
-            <div slot="footer" class="footer">
+            <div class="footer">
                 <el-button type="primary" @click="save" v-click-once>保存</el-button>
                 <el-button @click="cancel">取消</el-button>
-                </div>
+            </div>
         </el-card>
     </div>
 </template>
 <script>
 import MainBodyTemplate from './mainBodyTemplate.vue'
+import TinymceEditor from '@/components/TinymceEditor/index.vue';
 export default {
   components: {
-    MainBodyTemplate
+    MainBodyTemplate,
+    TinymceEditor
   },
 
   data() {
@@ -67,6 +71,7 @@ export default {
         documentNo: '',
         documentName: '',
         status: true,
+        content: ''
       },
       rules: {
         documentNo: [{ required: true, message: '请输入范文编号', trigger: 'blur' }],

+ 220 - 184
src/views/bpm/documents/documentTemplate/components/mainBodyTemplate.vue

@@ -1,237 +1,214 @@
 <template>
   <div class="main-body-template">
     <h2 class="title">发文通知稿纸</h2>
-    
-    <el-form :model="form" :rules="rules" ref="form">
-      <table class="table-container" border="1" cellpadding="10" cellspacing="0">
-        <!-- 第一行 -->
+
+    <el-form :model="form" :rules="rules" ref="form" label-width="0">
+      <table class="table-container" border="1" cellpadding="0" cellspacing="0">
+        <!-- 第一行:发文名称 + 发文字号/申请编码 -->
         <tr>
-          <td>发文名称</td>
-          <td colspan="1">
-            <el-form-item prop="documentName" style="margin: 0;">
-              <el-input v-model="form.documentName" placeholder="请输入"></el-input>
+          <td class="label required">发文名称</td>
+          <td colspan="2">
+            <el-form-item prop="documentName">
+              <el-input v-model="form.documentName" placeholder="请输入" />
             </el-form-item>
           </td>
-          <td>发文字号</td>
-          <td colspan="1">
-            <el-form-item prop="documentNumber" style="margin: 0;">
-              <el-input v-model="form.documentNumber" placeholder="请输入"></el-input>
+          <td class="label">发文字号</td>
+          <td colspan="2">
+            <el-form-item prop="documentNumber">
+              <el-input v-model="form.documentNumber" placeholder="请输入">
+                <template slot="append">
+                  <el-button type="text" size="mini" class="code-btn" @click="generateCode">申请编码</el-button>
+                </template>
+              </el-input>
             </el-form-item>
           </td>
         </tr>
+
+        <!-- 第二行:发文机关 + 拟稿人 -->
         <tr>
-          <td>申请编码</td>
-          <td colspan="3">
-            <el-input v-model="form.applicationCode" disabled style="width: 100%;"></el-input>
-          </td>
-        </tr>
-        
-        <!-- 第二行 -->
-        <tr>
-          <td>发文机关</td>
-          <td colspan="3">
-            <el-form-item prop="issuingAuthority" style="margin: 0;">
-              <el-select v-model="form.issuingAuthority" placeholder="请选择" style="width: 200px;">
-                <el-option label="办公室" value="办公室"></el-option>
-                <!-- 其他选项 -->
+          <td class="label required">发文机关</td>
+          <td colspan="2">
+            <el-form-item prop="issuingAuthority">
+              <el-select v-model="form.issuingAuthority" placeholder="请选择" style="width: 100%;">
+                <el-option label="办公室" value="办公室" />
               </el-select>
-              <el-checkbox v-model="form.jointIssuance" style="margin-left: 10px;">联合发文</el-checkbox>
             </el-form-item>
+            <div class="hint-text">修改发文机关,将移除主送机关、抄送机关、抄报机关、会签中选择的交换单位</div>
+            <el-checkbox v-model="form.jointIssuance">联合发文</el-checkbox>
           </td>
-        </tr>
-        <tr>
-          <td>拟稿人</td>
-          <td colspan="3">
-            <el-form-item prop="draftPerson" style="margin: 0;">
-              <el-input v-model="form.draftPerson" placeholder="请输入" style="width: 100%;">
-                <template slot="append">
-                  <el-button type="text" icon="el-icon-user"></el-button>
-                </template>
+          <td class="label">拟稿人</td>
+          <td colspan="2">
+            <el-form-item prop="draftPerson">
+              <el-input v-model="form.draftPerson" placeholder="请输入">
+                <el-button slot="append" icon="el-icon-user"></el-button>
               </el-input>
             </el-form-item>
           </td>
         </tr>
-        
-        <!-- 第三行 -->
+
+        <!-- 第三行:主送 + 抄送 -->
         <tr>
-          <td>主送</td>
-          <td colspan="3">
-            <el-form-item prop="mainRecipient" style="margin: 0;">
+          <td class="label">主送</td>
+          <td colspan="2">
+            <el-form-item prop="mainRecipient">
               <el-select v-model="form.mainRecipient" placeholder="请选择" multiple style="width: 100%;">
-                <!-- 选项 -->
               </el-select>
             </el-form-item>
           </td>
-        </tr>
-        <tr>
-          <td>抄送</td>
-          <td colspan="3">
-            <el-form-item prop="ccRecipient" style="margin: 0;">
+          <td class="label">抄送</td>
+          <td colspan="2">
+            <el-form-item prop="ccRecipient">
               <el-select v-model="form.ccRecipient" placeholder="请选择" multiple style="width: 100%;">
-                <!-- 选项 -->
               </el-select>
             </el-form-item>
           </td>
         </tr>
-        
-        <!-- 第四行 -->
+
+        <!-- 第四行:发文单位意见 -->
         <tr>
-          <td>发文单位意见</td>
-          <td colspan="3">
-            <el-form-item prop="unitOpinion" style="margin: 0;">
-              <el-input v-model="form.unitOpinion" placeholder="请输入" style="width: 100%;"></el-input>
+          <td class="label">发文单位意见</td>
+          <td colspan="4">
+            <el-form-item prop="unitOpinion">
+              <el-input v-model="form.unitOpinion" placeholder="请输入" />
             </el-form-item>
           </td>
         </tr>
+
+        <!-- 第五行:会办单位意见 + 核稿 -->
         <tr>
-          <td>核稿</td>
-          <td colspan="3">
-            <el-form-item prop="reviewer" style="margin: 0;">
-              <el-input v-model="form.reviewer" placeholder="请输入" style="width: 100%;"></el-input>
+          <td class="label">会办单位意见</td>
+          <td colspan="2">
+            <el-form-item prop="coUnitOpinion">
+              <el-input v-model="form.coUnitOpinion" placeholder="请输入" />
             </el-form-item>
           </td>
-        </tr>
-        
-        <!-- 第五行 -->
-        <tr>
-          <td>会办单位意见</td>
-          <td colspan="3">
-            <el-form-item prop="coUnitOpinion" style="margin: 0;">
-              <el-input v-model="form.coUnitOpinion" placeholder="请输入" style="width: 100%;"></el-input>
+          <td class="label">核稿</td>
+          <td colspan="2">
+            <el-form-item prop="reviewer">
+              <el-input v-model="form.reviewer" placeholder="请输入" />
             </el-form-item>
           </td>
         </tr>
-        
-        <!-- 第六行 -->
+
+        <!-- 第六行:主题词 -->
         <tr>
-          <td>主题词</td>
-          <td colspan="3">
-            <el-form-item prop="keywords" style="margin: 0;">
-              <el-input v-model="form.keywords" placeholder="请输入,按回车键多个主题词,用分号隔开" style="width: 100%;"></el-input>
+          <td class="label">主题词</td>
+          <td colspan="4">
+            <el-form-item prop="keywords">
+              <el-input v-model="form.keywords" placeholder="请输入,按回车键多个主题词,用分号隔开" />
             </el-form-item>
           </td>
         </tr>
-        
-        <!-- 第七行 -->
+
+        <!-- 第七行:领导批示 -->
         <tr>
-          <td>领导批示</td>
-          <td colspan="3">
-            <el-form-item prop="leaderInstruction" style="margin: 0;">
-              <el-input v-model="form.leaderInstruction" placeholder="请输入" style="width: 100%;"></el-input>
+          <td class="label">领导批示</td>
+          <td colspan="4">
+            <el-form-item prop="leaderInstruction">
+              <el-input v-model="form.leaderInstruction" placeholder="请输入" />
             </el-form-item>
           </td>
         </tr>
-        
-        <!-- 第八行 -->
+
+        <!-- 第八行:秘密等级 + 紧急程度 -->
         <tr>
-          <td>秘密等级</td>
-          <td>
-            <el-form-item prop="secretLevel" style="margin: 0;">
+          <td class="label required">秘密等级</td>
+          <td colspan="2">
+            <el-form-item prop="secretLevel">
               <el-select v-model="form.secretLevel" placeholder="请选择" style="width: 100%;">
-                <el-option label="公开" value="公开"></el-option>
-                <el-option label="内部" value="内部"></el-option>
-                <el-option label="秘密" value="秘密"></el-option>
-                <el-option label="机密" value="机密"></el-option>
-                <el-option label="绝密" value="绝密"></el-option>
+                <el-option label="普通" value="1" />
+                <el-option label="秘密" value="2" />
+                <el-option label="机密" value="3" />
+                <el-option label="绝密" value="4" />
               </el-select>
             </el-form-item>
           </td>
-          <td>紧急程度</td>
-          <td>
-            <el-form-item prop="urgencyLevel" style="margin: 0;">
+          <td class="label required">紧急程度</td>
+          <td colspan="2">
+            <el-form-item prop="urgencyLevel">
               <el-select v-model="form.urgencyLevel" placeholder="请选择" style="width: 100%;">
-                <el-option label="普通" value="普通"></el-option>
-                <el-option label="加急" value="加急"></el-option>
-                <el-option label="特急" value="特急"></el-option>
+                <el-option label="普通" value="1" />
+                <el-option label="紧急" value="2" />
+                <el-option label="特急" value="3" />
               </el-select>
             </el-form-item>
           </td>
         </tr>
-        
-        <!-- 第九行 -->
+
+        <!-- 第九行:保密期限 + 打印份数 -->
         <tr>
-          <td>保密期限</td>
-          <td>
-            <el-form-item prop="secretPeriod" style="margin: 0;">
-              <el-input v-model="form.secretPeriod" placeholder="请输入" style="width: 120px;"></el-input>
-              <el-select v-model="form.secretPeriodUnit" style="width: 80px;">
-                <el-option label="年" value="年"></el-option>
-                <el-option label="月" value="月"></el-option>
-                <el-option label="日" value="日"></el-option>
+          <td class="label">保密期限</td>
+          <td colspan="2">
+            <div class="input-with-unit">
+              <el-form-item prop="secretPeriod" style="flex: 1;">
+                <el-input v-model="form.secretPeriod" placeholder="请输入" />
+              </el-form-item>
+              <el-select v-model="form.secretPeriodUnit" style="width: 60px;">
+                <el-option label="年" value="年" />
+                <el-option label="月" value="月" />
+                <el-option label="日" value="日" />
               </el-select>
-            </el-form-item>
+            </div>
           </td>
-          <td>打印份数</td>
-          <td>
-            <el-form-item prop="printCopies" style="margin: 0;">
-              <el-input v-model="form.printCopies" placeholder="请输入" type="number" style="width: 100%;"></el-input>
+          <td class="label">打印份数</td>
+          <td colspan="2">
+            <el-form-item prop="printCopies">
+              <el-input v-model="form.printCopies" placeholder="请输入" />
             </el-form-item>
           </td>
         </tr>
-        
-        <!-- 第十行 -->
+
+        <!-- 第十行:印发机关 + 印发日期 -->
         <tr>
-          <td>印发机关</td>
-          <td>
-            <el-form-item prop="printingAuthority" style="margin: 0;">
+          <td class="label required">印发机关</td>
+          <td colspan="2">
+            <el-form-item prop="printingAuthority">
               <el-select v-model="form.printingAuthority" placeholder="请选择" style="width: 100%;">
-                <el-option label="办公室" value="办公室"></el-option>
-                <!-- 其他选项 -->
+                <el-option label="办公室" value="办公室" />
               </el-select>
             </el-form-item>
           </td>
-          <td>印发日期</td>
-          <td>
-            <el-form-item prop="printDate" style="margin: 0;">
-              <el-date-picker v-model="form.printDate" type="date" placeholder="选择日期" style="width: 100%;"></el-date-picker>
+          <td class="label">印发日期</td>
+          <td colspan="2">
+            <el-form-item prop="printDate">
+              <el-date-picker v-model="form.printDate" type="date" placeholder="选择日期" style="width: 100%;" />
             </el-form-item>
           </td>
         </tr>
-        
-        <!-- 第十一行 -->
+
+        <!-- 第十一行:说明 + 是否纳入督办 -->
         <tr>
-          <td>说明</td>
-          <td>
-            <el-form-item prop="description" style="margin: 0;">
-              <el-input v-model="form.description" placeholder="请输入" style="width: 100%;"></el-input>
+          <td class="label">说明</td>
+          <td colspan="2">
+            <el-form-item prop="description">
+              <el-input v-model="form.description" placeholder="请输入" />
             </el-form-item>
           </td>
-          <td>是否纳入督办</td>
-          <td>
-            <el-form-item prop="includeSupervision" style="margin: 0;">
+          <td class="label">是否纳入督办</td>
+          <td colspan="2">
+            <el-form-item prop="includeSupervision">
               <el-select v-model="form.includeSupervision" placeholder="请选择" style="width: 100%;">
-                <el-option label="是" value="是"></el-option>
-                <el-option label="否" value="否"></el-option>
+                <el-option label="是" :value="true" />
+                <el-option label="否" :value="false" />
               </el-select>
             </el-form-item>
           </td>
         </tr>
-        
-        <!-- 第十二行 -->
+
+        <!-- 第十二行:附件 -->
         <tr>
-          <td>附件</td>
-          <td colspan="3">
-            <el-form-item prop="attachments" style="margin: 0;">
-              <el-upload
-                class="upload-demo"
-                action="#"
-                :on-preview="handlePreview"
-                :on-remove="handleRemove"
-                :file-list="fileList"
-                :auto-upload="false"
-              >
-                <el-button size="small" type="primary">上传文件,请点击上传</el-button>
-                <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>
+          <td class="label">附件</td>
+          <td colspan="4">
+            <el-form-item prop="attachments">
+              <el-upload action="#" :auto-upload="false" :file-list="fileList">
+                <i class="el-icon-upload"></i>
+                <span class="upload-text">上传文件,请</span>
+                <el-button type="text">点击上传</el-button>
               </el-upload>
             </el-form-item>
           </td>
         </tr>
       </table>
-      
-      <div class="text-center" style="margin-top: 30px;">
-        <el-button type="primary" @click="submitForm">提交</el-button>
-        <el-button @click="resetForm">重置</el-button>
-      </div>
     </el-form>
   </div>
 </template>
@@ -241,19 +218,17 @@ export default {
   name: 'MainBodyTemplate',
   data() {
     return {
-      tableData: [{}], // 用于el-table的数据
       form: {
         documentName: '',
-        documentNumber: '',
-        applicationCode: 'PZ-00002-文本-202639',
+        documentNumber: 'PZ-00002-文本-202639',
         issuingAuthority: '',
         jointIssuance: false,
         draftPerson: '潘小帅(部门总监)',
         mainRecipient: [],
         ccRecipient: [],
         unitOpinion: '',
-        reviewer: '',
         coUnitOpinion: '',
+        reviewer: '',
         keywords: '',
         leaderInstruction: '',
         secretLevel: '',
@@ -264,7 +239,7 @@ export default {
         printingAuthority: '',
         printDate: '',
         description: '',
-        includeSupervision: '是',
+        includeSupervision: true,
         attachments: []
       },
       fileList: [],
@@ -291,70 +266,131 @@ export default {
     };
   },
   methods: {
-    handleRemove(file, fileList) {
-      console.log(file, fileList);
-    },
-    handlePreview(file) {
-      console.log(file);
+    generateCode() {
+      this.$message.success('生成申请编码');
     },
     submitForm() {
-      this.$refs.form.validate((valid) => {
+      this.$refs.form.validate(valid => {
         if (valid) {
-          alert('提交成功');
+          this.$message.success('提交成功');
         } else {
-          console.log('验证失败');
+          this.$message.error('请完善必填项');
           return false;
         }
       });
     },
     resetForm() {
       this.$refs.form.resetFields();
+      this.fileList = [];
     }
   }
 };
 </script>
 
-<style scoped>
+<style scoped lang="scss">
 .main-body-template {
   padding: 20px;
   background-color: #fff;
-  border-radius: 8px;
-  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
 }
 
 .title {
   text-align: center;
   color: #ff0000;
-  margin-bottom: 30px;
   font-size: 20px;
   font-weight: bold;
-}
-
-.el-form {
-  border: 1px solid #ff0000;
-  padding: 20px;
-  border-radius: 4px;
+  margin-bottom: 20px;
 }
 
 .table-container {
   width: 100%;
-  margin-bottom: 20px;
+  border-collapse: collapse;
   border: 1px solid #ff0000;
-  
+
   td {
     border: 1px solid #ff0000;
-    padding: 10px;
-    vertical-align: top;
+    padding: 8px 12px;
+    vertical-align: middle;
+    font-size: 14px;
   }
-  
-  td:first-child {
-    font-weight: bold;
+
+  .label {
+    color: #ff0000;
+    font-weight: normal;
     width: 150px;
+    text-align: left;
+    background-color: #fff;
+
+    &.required::after {
+      content: '*';
+      color: #ff0000;
+      margin-left: 4px;
+    }
+  }
+
+  .code-cell {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+
+    .code-text {
+      color: #606266;
+      font-size: 12px;
+    }
+
+    .code-btn {
+      padding: 0;
+      font-size: 12px;
+    }
+  }
+
+  .code-display {
+    color: #606266;
+    font-size: 12px;
+    margin-right: 8px;
+  }
+
+  .hint-text {
+    color: #ff0000;
+    font-size: 12px;
+    line-height: 1.4;
+    margin-top: 4px;
+  }
+
+  .input-with-unit {
+    display: flex;
+    align-items: center;
+    gap: 8px;
+  }
+
+  .upload-text {
+    color: #909399;
+    margin-left: 4px;
   }
 }
 
-.text-center {
+.form-actions {
   text-align: center;
-  margin-top: 30px;
+  margin-top: 20px;
+
+  .el-button {
+    margin: 0 10px;
+  }
+}
+
+::v-deep .el-form-item {
+  margin-bottom: 0;
+}
+
+::v-deep .el-input__inner,
+::v-deep .el-textarea__inner {
+  border: 1px solid #dcdfe6;
+
+  &:focus {
+    border-color: #409eff;
+  }
+}
+
+::v-deep .el-checkbox__label {
+  color: #606266;
 }
-</style>
+</style>