LinYeFangHuo/src/views/demo/layer/EditorModel.vue

183 lines
5.4 KiB
Vue

<template>
<BasicModal
v-bind="$attrs"
@register="registerModal"
title="样式编辑器"
:showCancelBtn="false"
:showOkBtn="false"
>
<div>
<div class="v-json-box">
<CodeEditor :value="editorJson" ref="myEditor" :mode="MODE.JSON" @change="changeHandle" />
</div>
<div class="copy-btn-box">
<a-button @click="formatting" type="primary">格式化文本</a-button>
<a-button @click="styleCancel">取消</a-button>
<a-button @click="editorSubmit" type="primary"></a-button>
</div>
</div>
</BasicModal>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { useMessage } from '@/hooks/web/useMessage';
import { BasicModal, useModalInner } from '@/components/Modal';
import { CodeEditor, MODE } from '@/components/CodeEditor';
import axios from 'axios';
import { getAppEnvConfig } from '@/utils/env';
import { fun_Delete } from '@/api/demo/files';
import { uploadSldStyle } from '@/api/application/layer';
const { VITE_GLOB_API_URL } = getAppEnvConfig();
async function fetchXMLDataWithAxios(url) {
try {
const response = await axios.get(url, { responseType: 'text' });
return response.data;
} catch (error) {
console.error('Error fetching XML data:', error);
}
}
const fileData = ref();
const { createMessage, createConfirm } = useMessage();
defineOptions({ name: 'MenuDrawer' });
const editorJson = ref();
const params: any = ref({});
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
console.log(data);
params.value.filepath = data.urlData.url;
params.value.styleName = data.styleName;
params.value.tablename = data.tableName;
setModalProps({ confirmLoading: false });
fileData.value = data.urlData;
// 使用方法
fetchXMLDataWithAxios(VITE_GLOB_API_URL + '/' + data.urlData.url).then((xmlDoc) => {
editorJson.value = xmlDoc;
});
});
const styleCancel = () => {
const params = [fileData.value.id];
createConfirm({
iconType: 'info',
title: '取消',
content: '取消会删除当前文件',
onOk: async () => {
fun_Delete(params).then((res) => {
createMessage.success('删除成功!');
closeModal();
});
},
});
};
const formatting = () => {
editorJson.value = formateXml(editorJson.value);
};
// 格式化 XML 的函数
function formateXml(xmlStr) {
let text = xmlStr;
// 使用 replace 去除多余空格
text =
'\n' +
text
.replace(/(<\w+)(\s.*?>)/g, function ($0, name, props) {
return name + ' ' + props.replace(/\s+(\w+=)/g, ' $1');
})
.replace(/></g, '>\n<');
// 处理注释
text = text
.replace(/\n/g, '\r')
.replace(/<!--(.+?)-->/g, function ($0, text) {
var ret = '<!--' + escape(text) + '-->';
return ret;
})
.replace(/\r/g, '\n');
// 调整格式,以压栈方式递归调整缩进
var rgx = /\n(<(([^\?]).+?)(?:\s|\s*?>|\s*?(\/)>)(?:.*?(?:(?:(\/)>)|(?:<(\/)\2>)))?)/gm;
var nodeStack = [];
var output = text.replace(
rgx,
function ($0, all, name, isBegin, isCloseFull1, isCloseFull2, isFull1, isFull2) {
var isClosed =
isCloseFull1 == '/' || isCloseFull2 == '/' || isFull1 == '/' || isFull2 == '/';
var prefix = '';
if (isBegin == '!') {
//!开头
prefix = setPrefix(nodeStack.length);
} else {
if (isBegin != '/') {
///开头
prefix = setPrefix(nodeStack.length);
if (!isClosed) {
// 非关闭标签
nodeStack.push(name);
}
} else {
nodeStack.pop(); // 弹栈
prefix = setPrefix(nodeStack.length);
}
}
var ret = '\n' + prefix + all;
return ret;
},
);
var prefixSpace = -1;
var outputText = output.substring(1);
// 处理数据为空的换行,将类似 <CostCurr3>\n </CostCurr3> 转换为 <CostCurr3> </CostCurr3>
// outputText = outputText.replace(/<([^>]+)>\s*<\/(\1)>/g, '<$1> </$1>');
// 还原注释内容
outputText = outputText
.replace(/\n/g, '\r')
.replace(/(\s*)<!--(.+?)-->/g, function ($0, prefix, text) {
if (prefix.charAt(0) == '\r') prefix = prefix.substring(1);
text = unescape(text).replace(/\r/g, '\n');
var ret = '\n' + prefix + '<!--' + text.replace(/^\s*/gm, prefix) + '-->';
return ret;
});
outputText = outputText.replace(/\s+$/g, '').replace(/\r/g, '\r\n');
return outputText;
}
// 计算缩进前缀的函数
function setPrefix(prefixIndex) {
var result = '';
var span = ' '; // 缩进长度
var output = [];
for (var i = 0; i < prefixIndex; ++i) {
output.push(span);
}
result = output.join('');
return result;
}
const changeHandle = (value) => {
editorJson.value = value;
};
const editorSubmit = () => {
console.log(params.value);
uploadSldStyle(params.value).then((res) => {
console.log(res);
if (res) {
closeModal();
createMessage.success('提交成功!');
} else {
createMessage.error('提交失败!');
}
});
};
</script>
<style lang="less" scoped>
.v-json-box {
height: 500px;
}
.copy-btn-box {
margin-top: 10px;
button {
margin-left: 20px;
}
}
</style>