671 lines
23 KiB
JavaScript
671 lines
23 KiB
JavaScript
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'); |