浏览代码

Merge branch 'master' of http://git.yangzhiqiang.tech/jiayq/ai-tagging

jiayongqiang 2 周之前
父节点
当前提交
1674148c6b

+ 17 - 23
web/src/views/aiTagging/externalPage/components/IntelligentRecommend.vue

@@ -78,16 +78,14 @@ export default {
     }
   },
   methods: {
-    // 选择标签(选,支持取消选中)
+    // 选择标签(选,支持取消选中)
     handleTagSelect(index) {
-      // 检查当前标签是否已选中
-      const isCurrentlySelected = this.recommendations[index].selected;
+      const currentTag = this.recommendations[index];
+      const isCurrentlySelected = currentTag.selected;
       
-      // 如果已选中,则取消所有标签的选中状态
+      // 如果已选中,则取消当前标签的选中状态
       if (isCurrentlySelected) {
-        this.recommendations.forEach(tag => {
-          tag.selected = false;
-        });
+        currentTag.selected = false;
         
         // 计算选中的标签
         const selectedTags = this.recommendations.filter(tag => tag.selected);
@@ -95,7 +93,6 @@ export default {
         this.$emit('tagSelect', selectedTags);
       } else {
         // 如果未选中,检查是否有反馈内容
-        const currentTag = this.recommendations[index];
         if (currentTag.feedback && currentTag.feedback.trim()) {
           // 提醒用户选中当前标签不准确反馈情况
           this.$confirm('当前标签有不准确反馈内容,是否确认选中该标签?选中后将清空反馈内容。', '提示', {
@@ -105,31 +102,28 @@ export default {
           }).then(() => {
             // 用户确认,清空反馈内容并选中标签
             currentTag.feedback = '';
-            this.selectTag(index);
+            currentTag.selected = true;
+            
+            // 计算选中的标签
+            const selectedTags = this.recommendations.filter(tag => tag.selected);
+            // 将选中的标签传递给父组件
+            this.$emit('tagSelect', selectedTags);
           }).catch(() => {
             // 用户取消,不做任何操作
             console.log('用户取消选中操作');
           });
         } else {
           // 没有反馈内容,直接选中标签
-          this.selectTag(index);
+          currentTag.selected = true;
+          
+          // 计算选中的标签
+          const selectedTags = this.recommendations.filter(tag => tag.selected);
+          // 将选中的标签传递给父组件
+          this.$emit('tagSelect', selectedTags);
         }
       }
     },
     
-    // 选中标签的内部方法
-    selectTag(index) {
-      // 取消其他标签的选中状态,只选中当前标签
-      this.recommendations.forEach((tag, i) => {
-        tag.selected = i === index;
-      });
-      
-      // 计算选中的标签
-      const selectedTags = this.recommendations.filter(tag => tag.selected);
-      // 将选中的标签传递给父组件
-      this.$emit('tagSelect', selectedTags);
-    },
-    
     // 处理切换到人工打标
     handleSwitchToManual() {
       // 判断是否选择了标签体系

+ 33 - 29
web/src/views/aiTagging/externalPage/components/ManualTagging.vue

@@ -28,7 +28,8 @@
         class="tag-tree-list"
         node-key="id"
         :highlight-current="true"
-        @node-click="handleTagClick"
+        :show-checkbox="true"
+        @check="handleTagCheck"
       ></el-tree>
     </div>
   </div>
@@ -113,9 +114,11 @@ export default {
       return data.tagNm && data.tagNm.toLowerCase().includes(value.toLowerCase());
     },
     
-    // 处理标签点击
-    handleTagClick(data, node, component) {
-      this.$emit('tagCheck', data, { checked: true });
+    // 处理标签勾选(支持多选切换)
+    handleTagCheck(data, checkInfo) {
+      // 根据checkInfo.checkedKeys判断当前节点是选中还是取消选中
+      const isChecked = checkInfo.checkedKeys.includes(data.id);
+      this.$emit('tagCheck', data, { checked: isChecked });
     },
     
     // 加载标签树数据
@@ -150,33 +153,34 @@ export default {
     
     // 反显选中的标签
     reverseSelectTags() {
-      if (!this.$refs.tagTree || !this.tagTreeData.length) {
-        return;
-      }
-      
-      // 遍历标签树,查找与已选标签匹配的节点
-      const findAndSelectTag = (nodes) => {
-        for (const node of nodes) {
-          // 检查当前节点的标签编码是否在已选标签列表中
-          const isSelected = this.selectedTags.some(selectedTag => 
-            selectedTag.tagCode === node.tagCode
-          );
-          if (isSelected) {
-            // 设置当前节点为选中状态
-            this.$refs.tagTree.setCurrentKey(node.id);
-            return true;
-          }
-          // 递归检查子节点
-          if (node.children && node.children.length) {
-            if (findAndSelectTag(node.children)) {
-              return true;
+      this.$nextTick(() => {
+        if (!this.$refs.tagTree || !this.tagTreeData.length) {
+          return;
+        }
+        
+        // 先清空所有选中状态
+        this.$refs.tagTree.setCheckedKeys([]);
+        
+        // 遍历标签树,查找与已选标签匹配的节点并勾选
+        const checkTagNodes = (nodes) => {
+          for (const node of nodes) {
+            // 检查当前节点的标签编码是否在已选标签列表中
+            const isSelected = this.selectedTags.some(selectedTag => 
+              selectedTag.tag_code === node.tagCode
+            );
+            if (isSelected) {
+              // 设置当前节点为选中状态
+              this.$refs.tagTree.setChecked(node.id, true, false);
+            }
+            // 递归检查子节点
+            if (node.children && node.children.length) {
+              checkTagNodes(node.children);
             }
           }
-        }
-        return false;
-      };
-      
-      findAndSelectTag(this.tagTreeData);
+        };
+        
+        checkTagNodes(this.tagTreeData);
+      });
     }
   }
 }

+ 21 - 16
web/src/views/aiTagging/externalPage/externalEdit.vue

@@ -438,7 +438,7 @@ export default {
       // 这里可以添加搜索标签的逻辑
     },
     
-    // 处理标签勾选
+    // 处理标签勾选(支持多选切换)
     handleTagCheck(data, checkedInfo) {
       console.log('勾选标签:', data, checkedInfo);
       
@@ -448,22 +448,27 @@ export default {
         return;
       }
       
-      // 过滤掉当前体系的标签,保留其他体系的标签
-      const otherSystemTags = this.selectedTags.filter(tag => tag.category_id !== selectedSystem.id);
+      const tagCode = data.tagCode || '';
       
-      // 添加当前选择的标签,按照要求的数据结构
-      const newSelectedTags = [...otherSystemTags, {
-        id: data.id || '',
-        desc: '',
-        passr: true,
-        tag_code: data.tagCode || '',
-        tag_name: data.tagNm || '',
-        tag_path: data.tagPath || '',
-        category_id: selectedSystem.id
-      }];
-      
-      // 更新已选标签
-      this.selectedTags = newSelectedTags;
+      if (checkedInfo.checked) {
+        // 选中:添加标签(如果不存在则添加)
+        const exists = this.selectedTags.some(tag => tag.tag_code === tagCode);
+        if (!exists) {
+          const newTag = {
+            id: data.id || '',
+            desc: '',
+            passr: true,
+            tag_code: tagCode,
+            tag_name: data.tagNm || '',
+            tag_path: data.tagPath || '',
+            category_id: selectedSystem.id
+          };
+          this.selectedTags = [...this.selectedTags, newTag];
+        }
+      } else {
+        // 取消选中:移除该标签
+        this.selectedTags = this.selectedTags.filter(tag => tag.tag_code !== tagCode);
+      }
       
       // 更新智能推荐的选中状态
       this.updateIntelligentSelectedState();

+ 49 - 3
web/src/views/aiTagging/externalPage/externalResult.vue

@@ -3,8 +3,9 @@
     <!-- 顶部通知栏 -->
     <div class="top-notification">
       <i class="el-icon-success"></i>
-      <span>标签已确认,您可以点击"编辑标签"按钮进行标签结果修改</span>
-      <el-button type="primary" class="edit-btn" @click="handleEditTags">编辑标签</el-button>
+      <span>标签已确认</span>
+      <span v-if="!isMappingChannel">,您可以点击"编辑标签"按钮进行标签结果修改</span>
+      <el-button type="primary" class="edit-btn" v-if="!isMappingChannel" @click="handleEditTags">编辑标签</el-button>
     </div>
     
     <!-- 标签详情列表 -->
@@ -45,6 +46,11 @@ export default {
     rawData: {
       type: Object,
       default: null
+    },
+    // 是否为映射打标渠道
+    isMappingChannel: {
+      type: Boolean,
+      default: false
     }
   },
   data() {
@@ -79,6 +85,46 @@ export default {
       // 从data中获取业务数据
       const businessData = data.data || data;
       
+      // isMappingChannel为true时,使用result数据源(映射打标)
+      if (this.isMappingChannel) {
+        let resultData = [];
+        
+        // 检查businessData是否有result字段
+        if (businessData.result) {
+          // 如果result是字符串,尝试解析为JSON
+          if (typeof businessData.result === 'string') {
+            try {
+              resultData = JSON.parse(businessData.result);
+            } catch (error) {
+              console.error('解析result失败:', error);
+              resultData = [];
+            }
+          } else {
+            // 如果result已经是数组或对象
+            resultData = businessData.result;
+          }
+        }
+        
+        // 检查resultData是否为数组
+        if (!Array.isArray(resultData)) {
+          console.error('resultData不是数组:', resultData);
+          this.tagResults = [];
+          return;
+        }
+        
+        // 构建标签结果数据,映射打标时打标方式统一显示为"映射打标"
+        this.tagResults = resultData.map(item => {
+          return {
+            tag_path: item.tag_path,
+            tag_method: '映射打标',
+            tag_basis: item.desc || '-'
+          };
+        });
+        
+        return;
+      }
+      
+      // 以下为原有逻辑:使用feedback_result数据源
       // 从feedback_result或result中获取标签数据
       let feedbackResult = [];
       let resultData = [];
@@ -145,7 +191,7 @@ export default {
           tagMethod = '智能打标';
           tagBasis = matchedResult.desc || '';
         } else {
-          // 如果没有找到匹配的标签,打标方式为人工打标,打标依据为“-”
+          // 如果没有找到匹配的标签,打标方式为人工打标,打标依据为"-"
           tagMethod = '人工打标';
           tagBasis = '-';
         }

+ 40 - 1
web/src/views/aiTagging/externalPage/index.vue

@@ -75,6 +75,7 @@
       <ExternalResult 
         v-else
         :raw-data="queryData"
+        :is-mapping-channel="taggingChannel == '2'"
         @edit="switchToEdit"
       />
   </div>
@@ -90,6 +91,18 @@ export default {
     ExternalEdit,
     ExternalResult
   },
+  props: {
+    // 测试模式标志
+    showType: {
+      type: String,
+      default: ''
+    },
+    // 测试数据(showType='test'时使用)
+    testData: {
+      type: Object,
+      default: null
+    }
+  },
   data() {
     return {
       // businessAttr
@@ -104,6 +117,8 @@ export default {
       currentState: 'edit',
       // 查询结果数据(统一变量)
       queryData: null,
+      // 打标渠道:'2' 表示映射打标
+      taggingChannel: null,
       // 用户数据,传递给ExternalEdit组件
       userData:{
         "user_id": "", 
@@ -121,7 +136,21 @@ export default {
     }
   },
   mounted() {
-    // 监听 postMessage 事件
+    // 测试模式:直接使用传入的testData
+    if (this.showType === 'test' && this.testData) {
+      this.businessAttr = this.testData.businessAttr || '';
+      this.userData = {
+        user_id: this.testData.userId || '',
+        user_nm: this.testData.userNm || '',
+        user_org: this.testData.userOrg || '',
+        user_endpoint: this.testData.userEndpoint || '',
+        contract_no: this.testData.contractNo || ''
+      };
+      this.queryBusinessAttr();
+      return;
+    }
+    
+    // 正常模式:监听 postMessage 事件
     this.setupPostMessageListener();
     
     // 页面加载完成后发送"页面已加载"消息
@@ -306,6 +335,16 @@ export default {
       // 获取state状态
       this.taggingState = data && data.data ? data.data.state : null;
       
+      // 获取taggingChannel打标渠道
+      this.taggingChannel = data && data.data ? data.data.tagging_channel : null;
+      
+      // tagging_channel == '2' 时,映射打标,直接显示结果状态
+      if (this.taggingChannel == '2') {
+        this.currentState = 'result';
+        this.queryData = data;  // 保存完整数据
+        return;
+      }
+      
       // 根据state状态处理不同的逻辑
       switch(this.taggingState) {
         case 0:

+ 7 - 3
web/src/views/aiTagging/taggingDetail/index.vue

@@ -72,8 +72,11 @@
         <div v-for="(result, index) in intelligentResults" :key="'intelligent-' + index" class="tagging-item">
           <div class="tagging-header">
             <div class="tag-path">{{ result.tagPath }}</div>
-            <el-tag size="small" :type="result.isCorrect === null ? 'info' : (result.isCorrect ? 'success' : 'danger')" effect="plain">
-              {{ result.isCorrect === null ? '' : (result.isCorrect ? '准确' : '不准确') }}
+            <el-tag v-if="taggingInfo.taggingChannel == '2'" size="small" type="info" effect="plain">
+              映射打标
+            </el-tag>
+            <el-tag v-else size="small" :type="result.isCorrect === null ? 'info' : (result.isCorrect ? 'success' : 'danger')" effect="plain">
+              {{ result.isCorrect === null ? '未反馈' : (result.isCorrect ? '准确' : '不准确') }}
             </el-tag>
           </div>
           
@@ -179,7 +182,8 @@ export default {
               feedbackUserOrg: data.feedbackUserOrg || '',
               feedbackUserEndpoint: data.feedbackUserEndpoint || '',
               feedbackTime: data.feedbackTime || '',
-              feedback: data.feedback || ''
+              feedback: data.feedback || '',
+              taggingChannel: data.taggingChannel || ''
             };
           } else {
             this.$message.error(response.message || '获取打标详情失败');

+ 20 - 2
web/src/views/aiTagging/taggingTest/taggingApply.vue

@@ -46,6 +46,18 @@
             <el-input v-model="userEndpoint" placeholder="请输入所属行社" style="width: 250px;"></el-input>
           </div>
         </div>
+
+        <!-- 第四行:行社代码 + 行社名称 -->
+        <div class="form-row">
+          <div class="form-item">
+            <label class="form-label">行社代码:</label>
+            <el-input v-model="instucde" placeholder="请输入行社代码" style="width: 250px;"></el-input>
+          </div>
+          <div class="form-item">
+            <label class="form-label">行社名称:</label>
+            <el-input v-model="instucdeNm" placeholder="请输入行社名称" style="width: 250px;"></el-input>
+          </div>
+        </div>
       </div>
       
       <!-- 打标内容 -->
@@ -123,6 +135,8 @@ export default {
       userNm: yufp.session.userName || '',
       userOrg: yufp.session.org ? yufp.session.org.name : '',
       userEndpoint: '',
+      instucde: '',
+      instucdeNm: '',
       // 智能打标结果
       taggingResults: [],
       // 是否未找到匹配的标签
@@ -202,7 +216,9 @@ export default {
         userId: this.userId,
         userNm: this.userNm,
         userOrg: this.userOrg,
-        userEndpoint: this.userEndpoint
+        userEndpoint: this.userEndpoint,
+        instucde: this.instucde,
+        instucdeNm: this.instucdeNm
       });
       
       // 显示加载提示
@@ -220,7 +236,9 @@ export default {
         userId: this.userId,
         userNm: this.userNm,
         userOrg: this.userOrg,
-        userEndpoint: this.userEndpoint
+        userEndpoint: this.userEndpoint,
+        instucde: this.instucde,
+        instucdeNm: this.instucdeNm
       };
       
       console.log('智能打标请求参数:', requestData);

+ 549 - 0
web/src/views/aiTagging/taggingTest/taggingConfirm-test.vue

@@ -0,0 +1,549 @@
+<template>
+  <div class="tagging-confirm">
+    <div class="confirm-container">
+      <!-- 左侧用户信息输入 -->
+      <div class="left-section">
+        <h4 class="section-title">用户信息输入</h4>
+        
+        <!-- 输入信息区域 -->
+        <el-form :model="formData" label-position="top" size="small">
+          <!-- 贷款申请编号 -->
+          <el-form-item label="贷款申请编号" prop="businessAttr">
+          <el-input v-model="formData.businessAttr" placeholder="请输入贷款申请编号" style="width: 100%;"></el-input>
+        </el-form-item>
+        
+        <!-- 合同编号 -->
+        <el-form-item label="合同编号" prop="contractNo">
+          <el-input v-model="formData.contractNo" placeholder="请输入合同编号" style="width: 100%;"></el-input>
+        </el-form-item>
+        
+        <!-- 用户ID -->
+        <el-form-item label="用户ID" prop="userId">
+          <el-input v-model="formData.userId" placeholder="请输入用户ID" />
+        </el-form-item>
+          
+          <!-- 用户姓名 -->
+          <el-form-item label="用户姓名" prop="userNm">
+            <el-input v-model="formData.userNm" placeholder="请输入用户姓名" style="width: 100%;"></el-input>
+          </el-form-item>
+          
+          <!-- 所属机构 -->
+          <el-form-item label="所属机构" prop="userOrg">
+            <el-input v-model="formData.userOrg" placeholder="请输入所属机构" style="width: 100%;"></el-input>
+          </el-form-item>
+          
+          <!-- 所属行社 -->
+          <el-form-item label="所属行社" prop="userEndpoint">
+            <el-input v-model="formData.userEndpoint" placeholder="请输入所属行社" style="width: 100%;"></el-input>
+          </el-form-item>
+        </el-form>
+        
+        <!-- 操作按钮 -->
+        <div class="input-actions">
+          <el-button @click="handleClear">清空</el-button>
+          <el-button type="primary" @click="handleConfirm">确认</el-button>
+        </div>
+      </div>
+      
+      <!-- 右侧externalPage组件展示 -->
+      <div class="right-section">
+        <h4 class="section-title">打标确认</h4>
+        <div class="iframe-container" v-if="showTestComponent">
+          <ExternalPage
+            :show-type="'test'"
+            :test-data="formData"
+          />
+        </div>
+        <div class="empty-iframe" v-else>
+          <img src="@/assets/images/noData.png" alt="暂无数据">
+          <p>请输入用户信息并点击确认按钮加载内容</p>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import ExternalPage from '@/views/aiTagging/externalPage/index.vue';
+
+export default {
+  name: 'TaggingConfirm',
+  components: {
+    ExternalPage
+  },
+  data() {
+    return {
+      // 表单数据
+      formData: {
+        // 贷款申请编号
+        businessAttr: '',
+        // 合同编号
+        contractNo: '',
+        // 用户信息
+        userId: yufp.session.userId || '',
+        userNm: yufp.session.userName || '',
+        userOrg: yufp.session.org ? yufp.session.org.name : '',
+        userEndpoint: ''
+      },
+      // 是否显示iframe
+      showIframe: false,
+      // iframe URL
+      iframeUrl: '',
+      // 是否显示测试组件
+      showTestComponent: false
+    }
+  },
+  mounted() {
+    // 监听来自externalPage的消息(包括页面加载完成和确认消息)
+    this.setupExternalPageListener();
+  },
+  beforeDestroy() {
+    // 清理事件监听器
+    this.removeExternalPageListener();
+  },
+  methods: {
+    // 设置externalPage监听器
+    setupExternalPageListener() {
+      this.handleExternalPageMessage = (event) => {
+        const data = event.data;
+        
+        // 检查是否为externalPage发送的页面加载完成消息
+        if (data && data.type === 'externalPageLoaded') {
+          // 如果已经输入了用户信息,自动发送数据
+          if (this.hasUserData()) {
+            this.sendDataToExternalPage();
+          }
+        }
+        
+        // 检查是否为externalPage发送的确认消息
+        else if (data && data.type === 'externalParamsReceived') {
+          // 移除临时确认监听器,避免重复处理
+          if (window.confirmationListener) {
+            window.removeEventListener('message', window.confirmationListener);
+            window.confirmationListener = null;
+          }
+        }
+      };
+      
+      window.addEventListener('message', this.handleExternalPageMessage);
+    },
+    
+    // 移除externalPage监听器
+    removeExternalPageListener() {
+      if (this.handleExternalPageMessage) {
+        window.removeEventListener('message', this.handleExternalPageMessage);
+      }
+    },
+    
+    // 检查是否已输入用户信息
+    hasUserData() {
+      return this.formData.businessAttr && 
+             this.formData.contractNo && 
+             this.formData.userId && 
+             this.formData.userNm;
+    },
+    
+    // 发送数据到externalPage
+    sendDataToExternalPage() {
+      if (!this.showIframe) {
+        return;
+      }
+      
+      const iframe = document.querySelector('iframe');
+      if (!iframe) {
+        return;
+      }
+      
+      // 监听iframe的load事件,确保页面完全加载完成
+      if (iframe.contentDocument && iframe.contentDocument.readyState === 'complete') {
+        // iframe已经加载完成,直接发送消息
+        this.sendMessageToIframe(iframe);
+      } else {
+        // iframe还在加载中,等待加载完成
+        
+        // 设置加载状态监听
+        let isMessageSent = false;
+        
+        iframe.onload = () => {
+          if (!isMessageSent) {
+            this.sendMessageToIframe(iframe);
+            isMessageSent = true;
+          }
+        };
+        
+        // 设置渐进式超时机制,适应不同网络环境
+        const timeouts = [5000, 10000, 15000]; // 5秒、10秒、15秒
+        
+        timeouts.forEach((timeout, index) => {
+          setTimeout(() => {
+            if (!isMessageSent) {
+              if (iframe.contentDocument && iframe.contentDocument.readyState === 'complete') {
+                this.sendMessageToIframe(iframe);
+                isMessageSent = true;
+              } else {
+                if (index === timeouts.length - 1) {
+                  // 最后一次超时,强制尝试发送消息
+                  this.sendMessageToIframe(iframe);
+                  isMessageSent = true;
+                }
+              }
+            }
+          }, timeout);
+        });
+      }
+    },
+    
+    // 确认按钮点击事件
+    handleConfirm() {
+      // 检查必填项
+      if (!this.formData.businessAttr) {
+        this.$message.warning('请输入贷款申请编号');
+        return;
+      }
+      if (!this.formData.contractNo) {
+        this.$message.warning('请输入合同编号');
+        return;
+      }
+      if (!this.formData.userId) {
+        this.$message.warning('请输入用户ID');
+        return;
+      }
+      if (!this.formData.userNm) {
+        this.$message.warning('请输入用户姓名');
+        return;
+      }
+      
+      // 显示测试组件
+      this.showTestComponent = true;
+    },
+    
+    // 模拟iframe访问发起逻辑
+    simulateIframeAccess() {
+    },
+    
+
+    
+    // 实际发送消息到iframe
+    sendMessageToIframe(iframe) {
+      if (!iframe.contentWindow) {
+        return;
+      }
+      
+      const messageData = {
+        type: 'externalParams',
+        business_attr: this.formData.businessAttr,
+        user_id: this.formData.userId,
+        user_nm: this.formData.userNm,
+        user_org: this.formData.userOrg,
+        user_endpoint: this.formData.userEndpoint,
+        contract_no: this.formData.contractNo,
+        timestamp: Date.now(),
+        source: 'taggingConfirm'
+      };
+      
+      try {
+        // 发送postMessage到iframe
+        iframe.contentWindow.postMessage(messageData, '*');
+        
+        // 监听来自iframe的确认消息
+        this.setupMessageConfirmation();
+      } catch (error) {
+        console.error('发送postMessage失败:', error);
+      }
+    },
+    
+    // 设置消息确认机制
+    setupMessageConfirmation() {
+      // 监听来自iframe的确认消息
+      const handleConfirmation = (event) => {
+        if (event.data && event.data.type === 'externalParamsReceived') {
+          // 移除事件监听器
+          window.removeEventListener('message', handleConfirmation);
+        }
+      };
+      
+      window.addEventListener('message', handleConfirmation);
+      
+      // 设置渐进式超时机制,适应网络延迟
+      const confirmationTimeouts = [10000, 20000, 30000]; // 10秒、20秒、30秒
+      
+      confirmationTimeouts.forEach((timeout, index) => {
+        setTimeout(() => {
+          if (window.confirmationListener === handleConfirmation) {
+            if (index === confirmationTimeouts.length - 1) {
+              // 最终超时
+              window.removeEventListener('message', handleConfirmation);
+            }
+          }
+        }, timeout);
+      });
+      
+      // 保存监听器引用,便于后续清理
+      window.confirmationListener = handleConfirmation;
+    },
+    
+    // 清空按钮点击事件
+    handleClear() {
+      // 清空所有输入
+      this.formData.businessAttr = '';
+      this.formData.userId = '';
+      this.formData.userNm = '';
+      this.formData.userOrg = '';
+      this.formData.userEndpoint = '';
+      // 隐藏iframe
+      this.showIframe = false;
+      this.iframeUrl = '';
+      
+      this.$message.info('已清空输入内容');
+    }
+  }
+}
+</script>
+
+<style scoped>
+.tagging-confirm {
+  height: 100%;
+}
+
+.confirm-container {
+  display: flex;
+  gap: 20px;
+  height: 100%;
+}
+
+/* 左侧用户信息输入区域 */
+.left-section {
+  flex: 0 0 200px;
+  background-color: #fafafa;
+  border-radius: 8px;
+  padding: 12px;
+  min-width: 190px;
+  max-width: 200px;
+}
+
+/* 右侧iframe展示区域 */
+.right-section {
+  flex: 2;
+  background-color: #fafafa;
+  border-radius: 8px;
+  padding: 20px;
+  height: 500px;
+  display: flex;
+  flex-direction: column;
+  min-height: 0; /* 重要:允许内容区域收缩 */
+}
+
+.section-title {
+  font-size: 14px;
+  font-weight: 600;
+  color: #303133;
+  margin: 0 0 16px 0;
+  text-align: left;
+  flex-shrink: 0; /* 标题不收缩 */
+}
+
+/* iframe容器样式 */
+.iframe-container {
+  flex: 1;
+  min-height: 0;
+  overflow: auto;
+  border: 1px solid #e4e7ed;
+  border-radius: 4px;
+  background-color: #fff;
+  display: flex;
+  flex-direction: column;
+  max-height: 100%;
+}
+
+.iframe-container iframe {
+  flex: 1;
+  width: 100%;
+  height: 100%;
+  border: none;
+  background-color: #fff;
+  overflow: auto;
+}
+
+/* 状态面板样式 */
+.status-panel {
+  background-color: #f8fafc;
+  border: 1px solid #e2e8f0;
+  border-radius: 6px;
+  padding: 12px 16px;
+  margin-bottom: 16px;
+  font-size: 13px;
+}
+
+.status-item {
+  display: flex;
+  align-items: center;
+  margin-bottom: 8px;
+}
+
+.status-item:last-child {
+  margin-bottom: 0;
+}
+
+.status-label {
+  font-weight: 600;
+  color: #4a5568;
+  min-width: 100px;
+  margin-right: 8px;
+}
+
+.status-value {
+  color: #2d3748;
+  font-family: 'Courier New', monospace;
+  background-color: #edf2f7;
+  padding: 2px 6px;
+  border-radius: 3px;
+  font-size: 12px;
+}
+
+.missing-tag {
+  margin-right: 4px;
+  margin-bottom: 4px;
+}
+
+/* 空iframe状态样式 */
+.empty-iframe {
+  flex: 1;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  background-color: #f8f9fa;
+  border: 1px dashed #dcdfe6;
+  border-radius: 4px;
+  color: #909399;
+}
+
+.empty-iframe img {
+  width: 80px;
+  height: 80px;
+  margin-bottom: 16px;
+  opacity: 0.6;
+}
+
+.empty-iframe p {
+  font-size: 14px;
+  margin: 0;
+}
+
+/* 输入信息区域 */
+/* 调整el-form样式 */
+.el-form {
+  margin-bottom: 16px;
+}
+
+.el-form-item {
+  margin-bottom: 12px;
+}
+
+.el-form-item__label {
+  font-size: 13px;
+  color: #606266;
+  padding-bottom: 4px;
+}
+
+/* 输入操作按钮 */
+.input-actions {
+  display: flex;
+  justify-content: space-between;
+  gap: 8px;
+  margin-top: 16px;
+  width: 100%;
+}
+
+/* 调整按钮大小 */
+.input-actions .el-button {
+  padding: 6px 12px;
+  font-size: 12px;
+  flex: 1;
+}
+
+/* 确认按钮样式 */
+.input-actions .el-button--primary {
+  flex: 1.5;
+}
+
+/* iframe容器 */
+.iframe-container {
+  flex: 1;
+  border: 1px solid #e8e8e8;
+  border-radius: 4px;
+  overflow: hidden;
+  background-color: #ffffff;
+}
+
+/* 空iframe提示 */
+.empty-iframe {
+  flex: 1;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  padding: 60px 20px;
+  color: #909399;
+  background-color: #fafafa;
+  min-height: 400px;
+}
+
+.empty-iframe img {
+  width: 120px;
+  height: 120px;
+  margin-bottom: 16px;
+  opacity: 0.6;
+}
+
+.empty-iframe p {
+  font-size: 14px;
+  color: #909399;
+  margin: 0;
+  line-height: 1.5;
+}
+
+/* 响应式设计 */
+@media (max-width: 768px) {
+  .confirm-container {
+    flex-direction: column;
+  }
+  
+  .left-section {
+    max-width: 100%;
+  }
+  
+  .right-section {
+    min-height: 400px;
+  }
+  
+  .form-row {
+    flex-direction: column;
+    gap: 16px;
+  }
+  
+  .form-item {
+    flex-direction: column;
+    align-items: flex-start;
+    min-width: auto;
+  }
+  
+  .form-label {
+    text-align: left;
+    margin-bottom: 8px;
+    width: 100%;
+  }
+  
+  .form-item .el-input {
+    width: 100% !important;
+  }
+  
+  .input-actions {
+    flex-direction: column;
+  }
+  
+  .input-actions .el-button {
+    width: 100%;
+  }
+}
+</style>