soureFile.vue 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. <!-- 源文件 -->
  2. <template>
  3. <div class="source" v-loading="loading">
  4. <el-input
  5. v-model="text"
  6. :rows="2"
  7. type="textarea"
  8. />
  9. </div>
  10. </template>
  11. <script setup>
  12. import { onMounted, watch, ref, inject } from "vue";
  13. import { getSourcexml } from "@/api/iedNetwork";
  14. import { useRoute } from "vue-router";
  15. const route = useRoute();
  16. const props = defineProps({
  17. checkData: {
  18. type: Object,
  19. default: () => {},
  20. },
  21. delScdId:{
  22. type:String,
  23. default: '',
  24. }
  25. });
  26. const loading = ref(true);
  27. const text = ref("");
  28. const setPrefix = function (prefixIndex) {
  29. let result = "";
  30. let span = " "; //缩进长度
  31. let output = [];
  32. for (let i = 0; i < prefixIndex; ++i) {
  33. output.push(span);
  34. }
  35. result = output.join("");
  36. return result;
  37. };
  38. const formateXml = function (xmlStr) {
  39. let text = xmlStr;
  40. //使用replace去空格
  41. text = text
  42. "\n" +
  43. text
  44. .replace(/(<\w+)(\s.*?>)/g, ($0, name, props) => {
  45. return name + " " + props.replace(/\s+(\w+=)/g, " $1");
  46. })
  47. .replace(/>\s*?</g, ">\n<");
  48. //处理注释,对注释进行编码
  49. text = text
  50. .replace(/\n/g, "\r")
  51. .replace(/<!--(.+?)-->/g, function ($0, text) {
  52. return "<!--" + escape(text) + "-->";
  53. })
  54. .replace(/\r/g, "\n");
  55. //调整格式 以压栈方式递归调整缩进
  56. let rgx =
  57. /\n(<(([^\?]).+?)(?:\s|\s*?>|\s*?(\/)>)(?:.*?(?:(?:(\/)>)|(?:<(\/)\2>)))?)/gm;
  58. let nodeStack = [];
  59. let output = text.replace(
  60. rgx,
  61. ($0, all, name, isBegin, isCloseFull1, isCloseFull2, isFull1, isFull2) => {
  62. let isClosed =
  63. isCloseFull1 == "/" ||
  64. isCloseFull2 == "/" ||
  65. isFull1 == "/" ||
  66. isFull2 == "/";
  67. let prefix = "";
  68. if (isBegin == "!") {
  69. //!开头
  70. prefix = setPrefix(nodeStack.length);
  71. } else {
  72. if (isBegin != "/") {
  73. ///开头
  74. prefix = setPrefix(nodeStack.length);
  75. if (!isClosed) {
  76. //非关闭标签
  77. nodeStack.push(name);
  78. }
  79. } else {
  80. nodeStack.pop(); //弹栈
  81. prefix = setPrefix(nodeStack.length);
  82. }
  83. }
  84. return "\n" + prefix + all;
  85. }
  86. );
  87. let outputText = output.substring(1);
  88. //还原注释内容
  89. outputText = outputText
  90. .replace(/\n/g, "\r")
  91. .replace(/(\s*)<!--(.+?)-->/g, function ($0, prefix, text) {
  92. if (prefix.charAt(0) == "\r") prefix = prefix.substring(1);
  93. // 解码
  94. text = window.unescape(text).replace(/\r/g, "\n");
  95. let ret = "\n" + prefix + "<!--" + text.replace(/^\s*/gm, prefix) + "-->";
  96. return ret;
  97. });
  98. return outputText;
  99. };
  100. const getHtml = async () => {
  101. const res = await getSourcexml({
  102. scd_id: scdIdValue,
  103. ied_name: props.checkData.ied_name,
  104. });
  105. text.value = formateXml(res.data);
  106. if (res) {
  107. loading.value = false;
  108. }
  109. };
  110. watch(
  111. () => props.checkData,
  112. (newValue) => {
  113. text.value = "";
  114. loading.value = true;
  115. if (newValue != null) {
  116. getHtml();
  117. }
  118. }
  119. );
  120. let scdIdValue = '';
  121. onMounted(() => {
  122. if (props.delScdId) {
  123. scdIdValue = props.delScdId;
  124. } else {
  125. scdIdValue = route.query.id;
  126. }
  127. getHtml();
  128. });
  129. </script>
  130. <style scoped lang="scss">
  131. .source {
  132. margin: 12px;
  133. border-radius: 2px;
  134. }
  135. :deep(.el-textarea__inner){
  136. height: 69vh;
  137. }
  138. .cont {
  139. border: 1px solid #d3d1d1;
  140. padding: 10px;
  141. }
  142. </style>