实习随笔【实现Json格式化与latex渲染】

【写在前面】在实习中,遇到了如下需求:

        待格式化数据大概长这样,里面存在Json乱码以及由$$包裹的公式

        目标格式: 

 一、Json格式化

我们这里的任务主要分为两部分:

  1. 解析一个可能包含嵌套的 JSON 字符串
  2. 格式化 JSON 对象

因为我们不知道后端返回的数据嵌套了多少层,所以均采用递归的方式,具体代码如下:

1、解析一个可能包含嵌套的 JSON 字符串
      parseAndFormatNestedJson(jsonString) {
        const recursiveParse = jsonStr => {
          try {
            let parsedData = JSON.parse(jsonStr);
            
            if (typeof parsedData === 'string') {
              return recursiveParse(parsedData);
            }
            
            for (let key in parsedData) {
              if (typeof parsedData[key] === 'string') {
                try {
                  parsedData[key] = recursiveParse(parsedData[key]);
                } catch (e) {
                  // 保留原始字符串
                }
              }
            }
            return parsedData;
          } catch (e) {
            return jsonStr;
          }
        };
  
        const parsedResult = recursiveParse(jsonString);
        return this.formatJson(parsedResult).replace(/\$\$/g, '$').replace(/\\\\/g, '\\');
      },

        这个函数的目的是解析一个可能包含嵌套的 JSON 字符串,并调用 formatJson 函数来格式化解析后的对象。处理过程如下:

  • 递归解析 (recursiveParse): 这是一个内部函数,使用递归来处理嵌套的 JSON 字符串。

    • 使用 JSON.parse 尝试解析输入的字符串 jsonStr
    • 如果解析后的结果是字符串类型,表示可能是嵌套的 JSON 字符串,因此再次调用 recursiveParse 来解析这个字符串。
    • 如果结果是一个对象,遍历该对象的每个属性。如果属性值是字符串类型,尝试对这个字符串进行递归解析。
    • 如果在解析过程中遇到异常(比如非法的 JSON 格式),会捕获异常并返回原始字符串。
  • 格式化和替换: 解析完成后的 JSON 对象通过 formatJson 进行格式化。格式化完成后,使用字符串替换来处理特殊字符,如将 $$ 替换为 $(方便展示),将 \\\\ 替换为 \\(处理异常)

2、格式化 JSON 对象
      formatJson(obj, level = 0) {
        const spaces = '  '.repeat(level);
        if (typeof obj !== 'object' || obj === null) {
          return JSON.stringify(obj);
        }
        
        if (Array.isArray(obj)) {
          const items = obj.map(item => `\n${spaces}  ${this.formatJson(item, level + 1)}`);
          return `[${items.join(', ')}\n${spaces}]`;
        } else {
          const entries = Object.entries(obj).map(([key, value]) => 
            `\n${spaces}  "${key}": ${this.formatJson(value, level + 1)}`
          );
          return `{${entries.join(', ')}\n${spaces}}`;
        }
      }

这个函数用于格式化 JSON 对象,使其更易于阅读。它支持递归格式化对象和数组。

  • 基础情况: 如果输入不是对象(包括数组),或者为 null,直接使用 JSON.stringify 来转换为字符串。
  • 数组处理: 如果是数组,对每个元素递归调用 formatJson 并增加缩进,然后将结果拼接成完整的数组格式。
  • 对象处理: 如果是对象,对每个键值对递归调用 formatJson 并增加缩进,然后将结果拼接成完整的对象格式。

二、渲染latex公式

    这里涉及到 第三方库 Mathjax 的使用,Mathjax具有强大的功能,配置好latex的规则后,可以自动识别 $$ / $ 包裹的公式,并将公式优雅的呈现在页面上。

1、引入并配置

        我这里使用的 cdn 引入的方式,在vue项目的 index.html 中 <head> 下配置

<!-- 配置 MathJax -->
    <script>
      window.MathJax = {
        tex: {
          inlineMath: [['$', '$'], ['\\(', '\\)']],
          displayMath: [['$$', '$$'], ['\\[', '\\]']]
        },
        svg: {
          fontCache: 'global'
        }
      };
    </script>
    <script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js" async></script>
2、组件中使用
<template>
    <div>
      <div id="json-container">{{ formattedJson }}</div>
      <!-- <div id="json-container">{{ this.parseAndFormatNestedJson(this.jsonString) }}</div> -->
    </div>
  </template>



 mounted() {
    this.$nextTick(() => {
    MathJax.typeset();
 });
3、配置样式

        配置到这里,你会发现页面上的公式正常渲染了,但是字符串的格式却乱了,所以需要加一些样式,代码如下:

#json-container {
        font-family: monospace;
        white-space: pre-wrap;
    }

        至此,整个Json格式化与渲染就完成了,希望对做同样需求的你,能够有所帮助,附上完整代码。

  • 配置文件 index.html
<!DOCTYPE html>
<html lang="">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <title><%= htmlWebpackPlugin.options.title %></title>
    <!-- 配置 MathJax -->
    <script>
      window.MathJax = {
        tex: {
          inlineMath: [['$', '$'], ['\\(', '\\)']],
          displayMath: [['$$', '$$'], ['\\[', '\\]']]
        },
        svg: {
          fontCache: 'global'
        }
      };
    </script>
    <script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js" async></script>
  </head>
  <body>
    <noscript>
      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>
  • 组件文件 Mathjax.vue
<template>
    <div>
      <div id="json-container">{{ formattedJson }}</div>
      <!-- <div id="json-container">{{ this.parseAndFormatNestedJson(this.jsonString) }}</div> -->
    </div>
  </template>
  
  <script>
  
  export default {
    name: 'JsonFormatter',
    data() {
      return {
        jsonString: "{\"msg\":\"ok\",\"code\":20000,\"data\":{\"result\":[{\"probs\":0.99942553043365479,\"texts\":\"如图,菱形ABCD的边长为4,且A\",\"char_info\":[{\"pos\":[{\"x\":0,\"y\":33},{\"x\":22,\"y\":33},{\"x\":22,\"y\":60},{\"x\":0,\"y\":60}],\"char\":\"如\",\"type\":1},{\"pos\":[{\"x\":22,\"y\":33},{\"x\":43,\"y\":33},{\"x\":43,\"y\":60},{\"x\":22,\"y\":60}],\"char\":\"图\",\"type\":1},{\"pos\":[{\"x\":43,\"y\":33},{\"x\":68,\"y\":33},{\"x\":68,\"y\":60},{\"x\":43,\"y\":60}],\"char\":\",\",\"type\":1},{\"pos\":[{\"x\":68,\"y\":33},{\"x\":95,\"y\":33},{\"x\":95,\"y\":60},{\"x\":68,\"y\":60}],\"char\":\"菱\",\"type\":1},{\"pos\":[{\"x\":95,\"y\":33},{\"x\":118,\"y\":33},{\"x\":118,\"y\":60},{\"x\":95,\"y\":60}],\"char\":\"形\",\"type\":1},{\"pos\":[{\"x\":118,\"y\":33},{\"x\":140,\"y\":33},{\"x\":140,\"y\":60},{\"x\":118,\"y\":60}],\"char\":\"A\",\"type\":1},{\"pos\":[{\"x\":140,\"y\":33},{\"x\":157,\"y\":33},{\"x\":157,\"y\":60},{\"x\":140,\"y\":60}],\"char\":\"B\",\"type\":1},{\"pos\":[{\"x\":157,\"y\":33},{\"x\":174,\"y\":33},{\"x\":174,\"y\":60},{\"x\":157,\"y\":60}],\"char\":\"C\",\"type\":1},{\"pos\":[{\"x\":174,\"y\":33},{\"x\":194,\"y\":33},{\"x\":194,\"y\":60},{\"x\":174,\"y\":60}],\"char\":\"D\",\"type\":1},{\"pos\":[{\"x\":194,\"y\":33},{\"x\":216,\"y\":33},{\"x\":216,\"y\":60},{\"x\":194,\"y\":60}],\"char\":\"的\",\"type\":1},{\"pos\":[{\"x\":216,\"y\":33},{\"x\":240,\"y\":33},{\"x\":240,\"y\":60},{\"x\":216,\"y\":60}],\"char\":\"边\",\"type\":1},{\"pos\":[{\"x\":240,\"y\":33},{\"x\":263,\"y\":33},{\"x\":263,\"y\":60},{\"x\":240,\"y\":60}],\"char\":\"长\",\"type\":1},{\"pos\":[{\"x\":263,\"y\":33},{\"x\":285,\"y\":33},{\"x\":285,\"y\":60},{\"x\":263,\"y\":60}],\"char\":\"为\",\"type\":1},{\"pos\":[{\"x\":285,\"y\":33},{\"x\":301,\"y\":33},{\"x\":301,\"y\":60},{\"x\":285,\"y\":60}],\"char\":\"4\",\"type\":1},{\"pos\":[{\"x\":301,\"y\":33},{\"x\":321,\"y\":33},{\"x\":321,\"y\":60},{\"x\":301,\"y\":60}],\"char\":\",\",\"type\":1},{\"pos\":[{\"x\":321,\"y\":33},{\"x\":348,\"y\":33},{\"x\":348,\"y\":60},{\"x\":321,\"y\":60}],\"char\":\"且\",\"type\":1},{\"pos\":[{\"x\":348,\"y\":33},{\"x\":375,\"y\":33},{\"x\":375,\"y\":60},{\"x\":348,\"y\":60}],\"char\":\"A\",\"type\":1}],\"variance\":0.0010391805553808808,\"poses\":[{\"x\":0,\"y\":33},{\"x\":375,\"y\":33},{\"x\":375,\"y\":60},{\"x\":0,\"y\":60}]},{\"probs\":0.98136389255523682,\"texts\":\"$$  E \\\\bot B C $$于E,$$  A F \\\\bot C D $$于F,$$  \\\\angle B = 6 $$\",\"char_info\":[{\"pos\":[{\"x\":73,\"y\":69},{\"x\":96,\"y\":69},{\"x\":96,\"y\":96},{\"x\":73,\"y\":96}],\"char\":\"于\",\"type\":1},{\"pos\":[{\"x\":96,\"y\":69},{\"x\":115,\"y\":69},{\"x\":115,\"y\":96},{\"x\":96,\"y\":96}],\"char\":\"E\",\"type\":1},{\"pos\":[{\"x\":115,\"y\":69},{\"x\":125,\"y\":69},{\"x\":125,\"y\":96},{\"x\":115,\"y\":96}],\"char\":\",\",\"type\":1},{\"pos\":[{\"x\":231,\"y\":70},{\"x\":252,\"y\":70},{\"x\":252,\"y\":96},{\"x\":231,\"y\":96}],\"char\":\"于\",\"type\":1},{\"pos\":[{\"x\":252,\"y\":70},{\"x\":269,\"y\":70},{\"x\":269,\"y\":96},{\"x\":252,\"y\":96}],\"char\":\"F\",\"type\":1},{\"pos\":[{\"x\":269,\"y\":70},{\"x\":279,\"y\":70},{\"x\":279,\"y\":96},{\"x\":269,\"y\":96}],\"char\":\",\",\"type\":1}],\"variance\":0.048195969313383102,\"poses\":[{\"x\":0,\"y\":70},{\"x\":373,\"y\":69},{\"x\":373,\"y\":94},{\"x\":0,\"y\":94}]},{\"probs\":0.99968928098678589,\"texts\":\"$$  0 ^ { \\\\circ } $$,则菱形ABCD的面积\",\"char_info\":[{\"pos\":[{\"x\":0,\"y\":104},{\"x\":41,\"y\":104},{\"x\":41,\"y\":133},{\"x\":0,\"y\":133}],\"char\":\",\",\"type\":1},{\"pos\":[{\"x\":41,\"y\":104},{\"x\":69,\"y\":104},{\"x\":69,\"y\":133},{\"x\":41,\"y\":133}],\"char\":\"则\",\"type\":1},{\"pos\":[{\"x\":69,\"y\":104},{\"x\":93,\"y\":104},{\"x\":93,\"y\":133},{\"x\":69,\"y\":133}],\"char\":\"菱\",\"type\":1},{\"pos\":[{\"x\":93,\"y\":104},{\"x\":117,\"y\":104},{\"x\":117,\"y\":133},{\"x\":93,\"y\":133}],\"char\":\"形\",\"type\":1},{\"pos\":[{\"x\":117,\"y\":104},{\"x\":139,\"y\":104},{\"x\":139,\"y\":133},{\"x\":117,\"y\":133}],\"char\":\"A\",\"type\":1},{\"pos\":[{\"x\":139,\"y\":104},{\"x\":157,\"y\":104},{\"x\":157,\"y\":133},{\"x\":139,\"y\":133}],\"char\":\"B\",\"type\":1},{\"pos\":[{\"x\":157,\"y\":104},{\"x\":173,\"y\":104},{\"x\":173,\"y\":133},{\"x\":157,\"y\":133}],\"char\":\"C\",\"type\":1},{\"pos\":[{\"x\":173,\"y\":104},{\"x\":192,\"y\":104},{\"x\":192,\"y\":133},{\"x\":173,\"y\":133}],\"char\":\"D\",\"type\":1},{\"pos\":[{\"x\":192,\"y\":104},{\"x\":215,\"y\":104},{\"x\":215,\"y\":133},{\"x\":192,\"y\":133}],\"char\":\"的\",\"type\":1},{\"pos\":[{\"x\":215,\"y\":104},{\"x\":239,\"y\":104},{\"x\":239,\"y\":133},{\"x\":215,\"y\":133}],\"char\":\"面\",\"type\":1},{\"pos\":[{\"x\":239,\"y\":104},{\"x\":269,\"y\":104},{\"x\":269,\"y\":133},{\"x\":239,\"y\":133}],\"char\":\"积\",\"type\":1}],\"variance\":0.00050142116378992796,\"poses\":[{\"x\":0,\"y\":104},{\"x\":269,\"y\":104},{\"x\":269,\"y\":133},{\"x\":0,\"y\":133}]},{\"probs\":0.92363280057907104,\"texts\":\"为___.\",\"char_info\":[{\"pos\":[{\"x\":0,\"y\":141},{\"x\":25,\"y\":141},{\"x\":25,\"y\":171},{\"x\":0,\"y\":171}],\"char\":\"为\",\"type\":1},{\"pos\":[{\"x\":25,\"y\":141},{\"x\":41,\"y\":141},{\"x\":41,\"y\":171},{\"x\":25,\"y\":171}],\"char\":\"_\",\"type\":1},{\"pos\":[{\"x\":41,\"y\":141},{\"x\":47,\"y\":141},{\"x\":47,\"y\":171},{\"x\":41,\"y\":171}],\"char\":\"_\",\"type\":1},{\"pos\":[{\"x\":47,\"y\":141},{\"x\":87,\"y\":141},{\"x\":87,\"y\":171},{\"x\":47,\"y\":171}],\"char\":\"_\",\"type\":1},{\"pos\":[{\"x\":87,\"y\":141},{\"x\":132,\"y\":141},{\"x\":132,\"y\":171},{\"x\":87,\"y\":171}],\"char\":\".\",\"type\":1}],\"variance\":0.15443108975887299,\"poses\":[{\"x\":0,\"y\":141},{\"x\":132,\"y\":141},{\"x\":132,\"y\":171},{\"x\":0,\"y\":171}]},{\"probs\":0.998046875,\"texts\":\"A\",\"char_info\":[{\"pos\":[{\"x\":64,\"y\":171},{\"x\":87,\"y\":171},{\"x\":87,\"y\":186},{\"x\":64,\"y\":186}],\"char\":\"A\",\"type\":1}],\"variance\":0,\"poses\":[{\"x\":64,\"y\":171},{\"x\":87,\"y\":171},{\"x\":87,\"y\":186},{\"x\":64,\"y\":186}]},{\"probs\":0.99951171875,\"texts\":\"B D\",\"char_info\":[{\"pos\":[{\"x\":0,\"y\":216},{\"x\":11,\"y\":216},{\"x\":11,\"y\":232},{\"x\":0,\"y\":232}],\"char\":\"B\",\"type\":1},{\"pos\":[{\"x\":12,\"y\":216},{\"x\":143,\"y\":216},{\"x\":143,\"y\":232},{\"x\":12,\"y\":232}],\"char\":\" \",\"type\":1},{\"pos\":[{\"x\":144,\"y\":216},{\"x\":159,\"y\":216},{\"x\":159,\"y\":232},{\"x\":144,\"y\":232}],\"char\":\"D\",\"type\":1}],\"variance\":0,\"poses\":[{\"x\":0,\"y\":216},{\"x\":159,\"y\":216},{\"x\":159,\"y\":232},{\"x\":0,\"y\":232}]},{\"probs\":1,\"texts\":\"E F\",\"char_info\":[{\"pos\":[{\"x\":32,\"y\":243},{\"x\":45,\"y\":243},{\"x\":45,\"y\":259},{\"x\":32,\"y\":259}],\"char\":\"E\",\"type\":1},{\"pos\":[{\"x\":46,\"y\":243},{\"x\":107,\"y\":243},{\"x\":107,\"y\":259},{\"x\":46,\"y\":259}],\"char\":\" \",\"type\":1},{\"pos\":[{\"x\":108,\"y\":243},{\"x\":122,\"y\":243},{\"x\":122,\"y\":259},{\"x\":108,\"y\":259}],\"char\":\"F\",\"type\":1}],\"variance\":0,\"poses\":[{\"x\":32,\"y\":243},{\"x\":122,\"y\":243},{\"x\":122,\"y\":259},{\"x\":32,\"y\":259}]},{\"probs\":0.99853515625,\"texts\":\"C\",\"char_info\":[{\"pos\":[{\"x\":69,\"y\":261},{\"x\":94,\"y\":261},{\"x\":94,\"y\":277},{\"x\":69,\"y\":277}],\"char\":\"C\",\"type\":1}],\"variance\":0,\"poses\":[{\"x\":69,\"y\":261},{\"x\":94,\"y\":261},{\"x\":94,\"y\":277},{\"x\":69,\"y\":277}]}],\"rotate\":0,\"images\":[{\"poses\":[{\"x\":0,\"y\":168},{\"x\":167,\"y\":168},{\"x\":167,\"y\":279},{\"x\":0,\"y\":279}]}],\"single_box\":{\"print_text\":[{\"texts\":\"如图,菱形ABCD的边长为4,且A\",\"Confidence\":0.99942553043365479,\"stdofconfi\":0.0010391805553808808,\"poses\":[{\"x\":0,\"y\":33},{\"x\":375,\"y\":33},{\"x\":375,\"y\":60},{\"x\":0,\"y\":60}]},{\"texts\":\"$$  0 ^ { \\\\circ } $$,则菱形ABCD的面积\",\"Confidence\":0.99968928098678589,\"stdofconfi\":0.00050142116378992796,\"poses\":[{\"x\":0,\"y\":104},{\"x\":269,\"y\":104},{\"x\":269,\"y\":133},{\"x\":0,\"y\":133}]},{\"texts\":\"为___.\",\"Confidence\":0.92363280057907104,\"stdofconfi\":0.15443108975887299,\"poses\":[{\"x\":0,\"y\":141},{\"x\":132,\"y\":141},{\"x\":132,\"y\":171},{\"x\":0,\"y\":171}]},{\"texts\":\"D\",\"Confidence\":1,\"stdofconfi\":0,\"poses\":[{\"x\":144,\"y\":216},{\"x\":159,\"y\":216},{\"x\":159,\"y\":232},{\"x\":144,\"y\":232}]},{\"texts\":\"B\",\"Confidence\":0.99951171875,\"stdofconfi\":0,\"poses\":[{\"x\":0,\"y\":216},{\"x\":11,\"y\":216},{\"x\":11,\"y\":232},{\"x\":0,\"y\":232}]},{\"texts\":\"于E,\",\"Confidence\":0.99951171875,\"stdofconfi\":0.00048828125,\"poses\":[{\"x\":73,\"y\":69},{\"x\":125,\"y\":69},{\"x\":125,\"y\":96},{\"x\":73,\"y\":96}]},{\"texts\":\"于F,\",\"Confidence\":0.96321612596511841,\"stdofconfi\":0.047707688063383102,\"poses\":[{\"x\":231,\"y\":70},{\"x\":279,\"y\":70},{\"x\":279,\"y\":96},{\"x\":231,\"y\":96}]},{\"texts\":\"F\",\"Confidence\":0.99951171875,\"stdofconfi\":0,\"poses\":[{\"x\":108,\"y\":243},{\"x\":122,\"y\":243},{\"x\":122,\"y\":259},{\"x\":108,\"y\":259}]},{\"texts\":\"E\",\"Confidence\":1,\"stdofconfi\":0,\"poses\":[{\"x\":32,\"y\":243},{\"x\":45,\"y\":243},{\"x\":45,\"y\":259},{\"x\":32,\"y\":259}]},{\"texts\":\"A\",\"Confidence\":0.998046875,\"stdofconfi\":0,\"poses\":[{\"x\":64,\"y\":171},{\"x\":87,\"y\":171},{\"x\":87,\"y\":186},{\"x\":64,\"y\":186}]},{\"texts\":\"C\",\"Confidence\":0.99853515625,\"stdofconfi\":0,\"poses\":[{\"x\":69,\"y\":261},{\"x\":94,\"y\":261},{\"x\":94,\"y\":277},{\"x\":69,\"y\":277}]}],\"print_formula\":[{\"texts\":\"$$  E \\\\bot B C $$\",\"Confidence\":0.99000000953674316,\"stdofconfi\":0,\"poses\":[{\"x\":0,\"y\":70},{\"x\":74,\"y\":70},{\"x\":74,\"y\":94},{\"x\":0,\"y\":94}]},{\"texts\":\"$$  A F \\\\bot C D $$\",\"Confidence\":0.99000000953674316,\"stdofconfi\":0,\"poses\":[{\"x\":138,\"y\":70},{\"x\":233,\"y\":70},{\"x\":233,\"y\":93},{\"x\":138,\"y\":94}]},{\"texts\":\"$$  \\\\angle B = 6 $$\",\"Confidence\":0.99000000953674316,\"stdofconfi\":0,\"poses\":[{\"x\":293,\"y\":70},{\"x\":373,\"y\":69},{\"x\":373,\"y\":94},{\"x\":293,\"y\":94}]},{\"texts\":\"$$  0 ^ { \\\\circ } $$\",\"Confidence\":0.99000000953674316,\"stdofconfi\":0,\"poses\":[{\"x\":0,\"y\":107},{\"x\":21,\"y\":107},{\"x\":21,\"y\":128},{\"x\":0,\"y\":128}]}]}}}"
      };
    },
    computed: {
      formattedJson() {
        return this.parseAndFormatNestedJson(this.jsonString);
      }
    },
    methods: {
      parseAndFormatNestedJson(jsonString) {
        const recursiveParse = jsonStr => {
          try {
            let parsedData = JSON.parse(jsonStr);
            
            if (typeof parsedData === 'string') {
              return recursiveParse(parsedData);
            }
            
            for (let key in parsedData) {
              if (typeof parsedData[key] === 'string') {
                try {
                  parsedData[key] = recursiveParse(parsedData[key]);
                } catch (e) {
                  // 保留原始字符串
                }
              }
            }
            return parsedData;
          } catch (e) {
            return jsonStr;
          }
        };
  
        const parsedResult = recursiveParse(jsonString);
        return this.formatJson(parsedResult).replace(/\$\$/g, '$').replace(/\\\\/g, '\\');
      },
      formatJson(obj, level = 0) {
        const spaces = '  '.repeat(level);
        if (typeof obj !== 'object' || obj === null) {
          return JSON.stringify(obj);
        }
        
        if (Array.isArray(obj)) {
          const items = obj.map(item => `\n${spaces}  ${this.formatJson(item, level + 1)}`);
          return `[${items.join(', ')}\n${spaces}]`;
        } else {
          const entries = Object.entries(obj).map(([key, value]) => 
            `\n${spaces}  "${key}": ${this.formatJson(value, level + 1)}`
          );
          return `{${entries.join(', ')}\n${spaces}}`;
        }
      }
    },
    mounted() {
      this.$nextTick(() => {
        MathJax.typeset();
      });
    }
  };
  </script>
  
  <style scoped>
    #json-container {
        font-family: monospace;
        white-space: pre-wrap;
    }
  </style>
  

  • 30
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值