const { createApp, ref, onMounted, nextTick } = Vue; const { ElMessage } = ElementPlus; const app = createApp({ setup() { // 从URL获取参数的函数 function getParameterByName(name, url = window.location.href) { debugger; name = name.replace(/[\[\]]/g, '\\$&'); const regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'); const results = regex.exec(url); if (!results) return null; if (!results[2]) return ''; return decodeURIComponent(results[2].replace(/\+/g, ' ')); } // 当用户完成操作时调用此函数 function returnSyntaxResult(result) { // 将结果存储到localStorage const resultKey = `syntaxResult_${windowId}`; localStorage.setItem(resultKey, JSON.stringify(result)); // 关闭窗口 window.close(); } // 过滤标记串(只保留型号码、前缀码、后缀码) const filterMarkString = (str) => { if (!str) return ''; // 匹配所有标记 const regex = /\[([^\]]+)=([^\]]+)\]/g; const matches = str.matchAll(regex); let validTags = []; debugger; switch(title.value) { case '线缆型号语法': validTags = ['型号码', '前缀码', '后缀码']; break; case '线缆规格语法': validTags = ['截面', '芯数', '线组数', '线对数']; break; case '电压等级语法': validTags = ['相电压', '线电压', '电压单位']; break; case '线缆标准语法': validTags = ['标准名']; break; default: // 默认为线缆型号语法 validTags = ['型号码', '前缀码', '后缀码']; } const filtered = []; for (const match of matches) { const tag = match[1]; if (validTags.includes(tag)) { filtered.push(`[${tag}=${match[2]}]`); } } return filtered.join(''); }; // 获取URL传递的参数 const urlParams = { title: getParameterByName('title') || '', ruleString: getParameterByName('ruleString1') || '', syntaxString: getParameterByName('syntaxString') || '', connectors: getParameterByName('connectors') || '' }; // 页面数据 const originalMarkString = ref(urlParams.ruleString); const syntaxString = ref(urlParams.syntaxString); // 使用传递的语法串 const orgsyntaxString = ref(urlParams.syntaxString); const cursorPosition = ref(-1); const syntaxEditor = ref(null); const actualValue = ref(''); const title = ref(urlParams.title); const filteredMarkString = ref(filterMarkString(urlParams.ruleString)); // 对话框相关 const showMarkDialog = ref(false); const showConnectorDialog = ref(false); const selectedConnector = ref(''); const availableMarks = ref([]); const predefinedConnectors = ref(urlParams.connectors.split(',')); const loadingConnectors = ref(false); const customConnector = ref(''); // 更新光标位置 const updateCursorPosition = () => { if (syntaxEditor.value) { cursorPosition.value = syntaxEditor.value.selectionStart; } }; const updateActualValue = () => { // 解析标记串中的所有标记(按顺序) const markArray = []; const markRegex = /\[([^\]]+)=([^\]]+)\]/g; let markMatch; while ((markMatch = markRegex.exec(filteredMarkString.value)) !== null) { markArray.push({ tag: markMatch[1], value: markMatch[2] }); } // 解析语法串 let result = ''; const syntaxRegex = /(\[[^\]]+\])|([^[]+)/g; let syntaxMatch; while ((syntaxMatch = syntaxRegex.exec(syntaxString.value)) !== null) { if (syntaxMatch[1]) { // 处理标记字部分 const innerRegex = /\[([^\]]+)([a-z])\]/; const innerMatch = syntaxMatch[1].match(innerRegex); if (innerMatch) { const tag = innerMatch[1]; const char = innerMatch[2]; const index = char.charCodeAt(0) - 97; // a->0, b->1, etc. // 检查索引是否在标记数组范围内 if (index < markArray.length) { // 获取对应位置的标记 const mark = markArray[index]; // 检查标记类型是否匹配 if (mark.tag === tag) { result += mark.value; } } } } else if (syntaxMatch[2]) { // 处理普通文本(链接符) result += syntaxMatch[2]; } } actualValue.value = result; }; // 打开插入标记字对话框 const openInsertMarkDialog = () => { // 解析语法串中的所有标记字 availableMarks.value = []; const regex = /\[[^\]]+\]/g; const matches = orgsyntaxString.value.match(regex) || []; // 去重 const uniqueMarks = [...new Set(matches)]; if (uniqueMarks.length > 0) { availableMarks.value = uniqueMarks; showMarkDialog.value = true; } else { ElMessage.warning('语法串中没有可用的标记字'); } }; // 插入选中的标记字 const insertSelectedMark = (mark) => { if (!syntaxEditor.value || !syntaxString.value) { ElMessage.warning('语法串为空'); return; } const text = syntaxString.value; const cursorPos = cursorPosition.value; // 检查光标位置是否在标记字内 let i = cursorPos; let insideBracket = false; if (i > 0) { while (i > 0) { const char = text.charAt(i - 1); if (char === ']') { break; } if (char === '[') { insideBracket = true; break; } i--; } } if (insideBracket) { ElMessage.warning('请将光标置于标记字[]之外'); showMarkDialog.value = false; return; } // 分割字符串 const before = text.substring(0, cursorPos); const after = text.substring(cursorPos); // 插入标记字 syntaxString.value = before + mark + after; // 更新实际值 updateActualValue(); // 设置光标位置到插入内容之后 nextTick(() => { const newCursorPos = cursorPos + mark.length; syntaxEditor.value.setSelectionRange(newCursorPos, newCursorPos); cursorPosition.value = newCursorPos; }); showMarkDialog.value = false; ElMessage.success(`已插入标记字: ${mark}`); }; // 打开插入链接符对话框 const openInsertConnectorDialog = () => { showConnectorDialog.value = true; selectedConnector.value = ''; // 清空前一次选择 customConnector.value = ''; // 清空前一次自定义输入 }; // 处理选择变化 const handleConnectorChange = (value) => { // 如果是自定义输入且不在预定义列表中 if (value && !predefinedConnectors.value.includes(value)) { customConnector.value = value; } }; // 插入选中的链接符 const insertSelectedConnector = (connector) => { if (!syntaxEditor.value || !syntaxString.value) { ElMessage.warning('语法串为空'); return; } const text = syntaxString.value; const cursorPos = cursorPosition.value; // 检查光标位置是否在标记字内 let i = cursorPos; let insideBracket = false; if (i > 0) { while (i > 0) { const char = text.charAt(i - 1); if (char === ']') { break; } if (char === '[') { insideBracket = true; break; } i--; } } if (insideBracket) { ElMessage.warning('请将光标置于标记字[]之外'); showConnectorDialog.value = false; return; } // 分割字符串 const before = text.substring(0, cursorPos); const after = text.substring(cursorPos); // 插入链接符 syntaxString.value = before + connector + after; // 更新实际值 updateActualValue(); // 设置光标位置到插入内容之后 nextTick(() => { const newCursorPos = cursorPos + connector.length; syntaxEditor.value.setSelectionRange(newCursorPos, newCursorPos); cursorPosition.value = newCursorPos; }); showConnectorDialog.value = false; ElMessage.success(`已插入链接符: ${connector}`); }; // 删除链接符 const deleteConnector = () => { if (!syntaxEditor.value || !syntaxString.value) { ElMessage.warning('语法串为空'); return; } const text = syntaxString.value; const cursorPos = cursorPosition.value; if (text.trim() === '') { return; } // 初始化起始和结束位置 let iStart = cursorPos; let iEnd = cursorPos; // 向左查找 let i = cursorPos; if (i >= 0) { while (i > 0) { const char = text.charAt(i - 1); if (char === ']') { iStart = i; break; } if (char === '[') { ElMessage.warning('请将光标置于语法串中的连接符位置'); return; } i--; } if (i === 0) { iStart = 0; } } // 向右查找 i = cursorPos; if (i >= 0) { while (i < text.length) { const char = text.charAt(i); if (char === '[') { iEnd = i; break; } i++; } if (i === text.length) { iEnd = text.length; } } // 构建新字符串 let newText = ''; if (iStart === 0) { newText = text.substring(iEnd); } else { newText = text.substring(0, iStart) + text.substring(iEnd); } syntaxString.value = newText; // 更新实际值 updateActualValue(); // 设置光标位置 nextTick(() => { syntaxEditor.value.setSelectionRange(iStart, iStart); cursorPosition.value = iStart; }); ElMessage.info('已删除链接符'); }; // 获取当前标记字内容 const getCurrentBracketContent = (text, cursorPos) => { let startIndex = -1; let endIndex = -1; // 查找当前标记字的起始位置 let i = 1; while (i <= cursorPos) { if (text.charAt(i - 1) === '[') { startIndex = i - 1; } i++; } // 查找当前标记字的结束位置 i = cursorPos; while (i < text.length) { if (text.charAt(i) === ']') { endIndex = i; break; } i++; } if (startIndex !== -1 && endIndex !== -1 && startIndex < endIndex) { return { content: text.substring(startIndex, endIndex + 1), start: startIndex, end: endIndex }; } return null; }; // 获取下一个标记字内容 const getNextBracketContent = (text, afterIndex) => { let startIndex = -1; let endIndex = -1; // 查找下一个标记字的起始位置 let i = afterIndex + 1; while (i < text.length) { if (text.charAt(i) === '[') { startIndex = i; break; } i++; } // 查找下一个标记字的结束位置 if (startIndex !== -1) { i = startIndex; while (i < text.length) { if (text.charAt(i) === ']') { endIndex = i; break; } i++; } } if (startIndex !== -1 && endIndex !== -1) { return { content: text.substring(startIndex, endIndex + 1), start: startIndex, end: endIndex }; } return null; }; // 获取前一个标记字内容 const getPreviousBracketContent = (text, beforeIndex) => { let startIndex = -1; let endIndex = -1; // 查找前一个标记字的起始位置 let i = 1; let lastStart = -1; while (i < beforeIndex) { if (text.charAt(i - 1) === '[') { lastStart = i - 1; } i++; } if (lastStart !== -1) { startIndex = lastStart; // 查找前一个标记字的结束位置 i = lastStart; while (i < beforeIndex) { if (text.charAt(i) === ']') { endIndex = i; } i++; } } if (startIndex !== -1 && endIndex !== -1) { return { content: text.substring(startIndex, endIndex + 1), start: startIndex, end: endIndex }; } return null; }; // 后移标记字 const moveMarkBackward = () => { if (!syntaxEditor.value || !syntaxString.value) { ElMessage.warning('语法串为空'); return; } const text = syntaxString.value; const cursorPos = cursorPosition.value; // 获取当前标记字 const currentMark = getCurrentBracketContent(text, cursorPos); if (!currentMark) { ElMessage.warning('请将光标置于需要移动的标记字内'); return; } // 获取下一个标记字 const nextMark = getNextBracketContent(text, currentMark.end); if (!nextMark) { ElMessage.warning('后面没有可交换的标记字'); return; } // 交换两个标记字 const before = text.substring(0, currentMark.start); const between = text.substring(currentMark.end + 1, nextMark.start); const after = text.substring(nextMark.end + 1); syntaxString.value = before + nextMark.content + between + currentMark.content + after; // 更新实际值 updateActualValue(); // 设置光标位置到移动后的标记字起始位置 nextTick(() => { const newCursorPos = before.length + nextMark.content.length + between.length; syntaxEditor.value.setSelectionRange(newCursorPos, newCursorPos); cursorPosition.value = newCursorPos; }); }; // 前移标记字 const moveMarkForward = () => { if (!syntaxEditor.value || !syntaxString.value) { ElMessage.warning('语法串为空'); return; } const text = syntaxString.value; const cursorPos = cursorPosition.value; // 获取当前标记字 const currentMark = getCurrentBracketContent(text, cursorPos); if (!currentMark) { ElMessage.warning('请将光标置于需要移动的标记字内'); return; } // 获取前一个标记字 const previousMark = getPreviousBracketContent(text, currentMark.start); if (!previousMark) { ElMessage.warning('前面没有可交换的标记字'); return; } // 交换两个标记字 const before = text.substring(0, previousMark.start); const between = text.substring(previousMark.end + 1, currentMark.start); const after = text.substring(currentMark.end + 1); syntaxString.value = before + currentMark.content + between + previousMark.content + after; // 更新实际值 updateActualValue(); // 设置光标位置到移动后的标记字起始位置 nextTick(() => { const newCursorPos = before.length; syntaxEditor.value.setSelectionRange(newCursorPos, newCursorPos); cursorPosition.value = newCursorPos; }); }; // 删除标记字 const deleteMark = () => { if (!syntaxEditor.value || !syntaxString.value) { return; } const text = syntaxString.value; const cursorPos = cursorPosition.value; // 获取当前标记字 const currentMark = getCurrentBracketContent(text, cursorPos); if (!currentMark) { ElMessage.warning('请将光标置于需要删除的标记字内'); return; } // 删除标记字 const before = text.substring(0, currentMark.start); const after = text.substring(currentMark.end + 1); syntaxString.value = before + after; // 更新实际值 updateActualValue(); // 设置光标位置 nextTick(() => { syntaxEditor.value.setSelectionRange(currentMark.start, currentMark.start); cursorPosition.value = currentMark.start; }); ElMessage.info('已删除标记字'); }; // 保存语法设置 const saveSyntax = () => { const result = { type: title.value, Value: syntaxString.value, ActualValue: actualValue.value }; window.parent.postMessage({ type: 'SAVE_SYNTAX_RESULT', payload: result }, '*'); ElMessage.success('语法规则已保存'); }; // 应用语法设置 const applySyntax = () => { ElMessage.success('语法规则已成功应用'); setTimeout(() => { window.close(); }, 1000); }; // 重置表单 const resetForm = () => { syntaxString.value = urlParams.syntaxString; // 重置为初始传递的值 actualValue.value = ''; cursorPosition.value = -1; updateActualValue(); // 重新计算实际值 }; // 关闭窗口 const closeWindow = () => { window.close(); }; // 初始化 onMounted(() => { updateActualValue(); }); return { filteredMarkString, syntaxString, cursorPosition, syntaxEditor, actualValue, showMarkDialog, showConnectorDialog, availableMarks, predefinedConnectors, updateCursorPosition, openInsertMarkDialog, insertSelectedMark, openInsertConnectorDialog, insertSelectedConnector, selectedConnector, deleteConnector, moveMarkForward, moveMarkBackward, deleteMark, saveSyntax, applySyntax, resetForm, closeWindow, handleConnectorChange, title }; } }); app.use(ElementPlus); app.mount('#app');