在线代码编辑器

在线代码编辑器

    • 文章说明
    • 前台核心代码
    • 后台核心代码
    • 效果展示
    • 源码下载

文章说明

采用Java结合vue3设计实现的在线代码编辑功能,支持在线编辑代码、运行代码,同时支持导入文件,支持图片识别,支持复制代码,可将代码导出为图片

暂时还未添加图片代码识别导入的功能,然后目前Linux版本下安装C#的编译器我还没找到好的方案,这个C#代码运行在Linux环境下暂时有点问题

目前对于代码安全方面还未添加校验,只作为简单的学习使用,存在着不小的风险,后续会考虑新开坑,书写更完善的在线编辑器

目前的这个结果展示的编码方面还有一些问题,主要是控制台输入、命令行以及文件本身的编码会有不一致的情况,有些难整,后续考虑采用新方案给这个问题解决一下

前台核心代码

前台主要采用 md-editor-v3 编辑器作为代码编辑区域,虽然没有提示功能,但是展示效果上会好一些,然后运行的时候调用后台接口,采用Java调用cmd命令行来实现代码的运行

其中代码下载为图片采用的是对dom对象进行下载,采用html2canvas来实现,会有一些小bug,不过效果感觉还可以

前台核心代码

<script setup>
import {MdEditor, MdPreview} from 'md-editor-v3';
import 'md-editor-v3/lib/style.css';
import 'md-editor-v3/lib/preview.css';
import {computed, onBeforeMount, reactive, ref, watch} from "vue";
import html2canvas from "html2canvas";
import {confirm,downloadFileToLocalByUrl,exportCommon,getRequest,loading,message,postRequest,prompt
} from "@/util";const data = reactive({language: "",codeText: "",inputText: "",displayText: "",exportDialogVisible: false,exportImgUrl: "",uploadExist: true,
});const languageList = ["Java","Python","Javascript","C","C++","C#",
];const codeText = computed(() => {return "```" + data.language + "\n" + data.codeText + "\n```"
});function exportCodeToImg() {const displayContent = document.getElementsByClassName("display-content")[0];data.exportDialogVisible = true;html2canvas(displayContent, {}).then((canvas) => {data.exportImgUrl = canvas.toDataURL('image/png');});
}function exportCode() {prompt("导出代码文件", "导出代码文件名称", data.language + "_" + new Date().toLocaleString() + ".txt", (value) => {exportCommon(data.codeText, value);});
}function exportCodeToImgConfirm() {prompt("导出代码图片", "导出代码图片名称", data.language + "_" + new Date().toLocaleString() + ".png", (value) => {downloadFileToLocalByUrl(data.exportImgUrl, value);data.exportDialogVisible = false;});
}function reset() {confirm("确认清空吗,包括代码区域、控制台文件输入以及结果展示区域?", () => {data.codeText = "";data.inputText = "";data.displayText = "";});
}function run() {if (!data.language) {message("请先选择编程语言", "warning");return;}const loadingInstance = loading("运行中...");postRequest("/codeRunner/run", null, {language: data.language,codeText: data.codeText,inputText: data.inputText,}).then((res) => {loadingInstance.close();if (res.data.code === 200) {data.displayText = res.data.data;message("代码运行成功", "success");} else if (res.data.code === 500) {message("代码运行失败", "error");}})
}const languageText = {};onBeforeMount(async () => {for (let i = 0; i < languageList.length; i++) {languageText[languageList[i]] = await getLanguageDefaultText(languageList[i]);}
});async function getLanguageDefaultText(language) {const res = await getRequest("/codeRunner/getDefaultText", {language});if (res.data.code === 200) {return res.data.data;} else if (res.data.code === 500) {message(language + "语言默认代码获取失败", "error");}
}watch(() => data.language, (newValue, oldValue) => {if (data.codeText) {languageText[oldValue] = data.codeText;}data.codeText = languageText[data.language];
});const uploadFileRef = ref();function uploadFile(event) {const loadingInstance = loading("导入中...");const file = event.target.files[0];const reader = new FileReader();reader.readAsText(file, 'utf8');data.uploadExist = false;reader.onload = () => {loadingInstance.close();const codeText = reader.result.toString();data.uploadExist = true;if (!codeText) {message("导出文件内容为空", "warning");return;}data.codeText = codeText;}
}function singleImport() {if (!data.language) {message("请先选择编程语言", "warning");return;}if (!data.uploadExist) {return;}uploadFileRef.value.click();
}
</script><template><div class="container"><div class="tool-bar"><div class="row"><el-select v-model="data.language" placeholder="请选择编程语言" style="width: 80%"><template v-for="item in languageList" :key="item"><el-option :label="item" :value="item"/></template></el-select></div><div class="row" style="margin-top: -0.5rem"><el-button type="primary" @click="run">运行</el-button><el-button type="danger" @click="reset">清空</el-button><el-button type="danger" @click="singleImport">导入代码</el-button><input v-if="data.uploadExist" ref="uploadFileRef" accept=".txt,.java,.py,.js,.c,.cpp,.cs" style="display: none"type="file" @change="uploadFile($event)"></div><div class="row" style="margin-top: -0.5rem"><el-button type="primary" @click="exportCode">导出代码</el-button><el-button type="danger" @click="exportCodeToImg">下载为图片</el-button></div></div><div class="content-container"><div class="editor-content"><MdEditor v-model="data.codeText" :preview="false" :toolbars="[]" placeholder="代码输入区域"style="height: 100%; width: 100%" theme="dark"/></div><div class="display-content"><MdPreview v-model="codeText" :show-code-row-number="false" style="height: 100%; width: 100%"/></div><div class="input-content"><MdEditor v-model="data.inputText" :preview="false" :toolbars="[]" placeholder="控制台文件输入区域"style="height: 100%; width: 100%" theme="dark"/></div><div class="result-content"><MdEditor v-model="data.displayText" :preview="false" :toolbars="[]" placeholder="结果展示区域" read-onlystyle="height: 100%; width: 100%" theme="dark"/></div></div></div><el-dialog v-model="data.exportDialogVisible" title="代码下载为图片" width="90%"><img :src="data.exportImgUrl" alt="" style="width: 100%; height: auto"/><template #footer><el-button type="primary" @click="data.exportDialogVisible = false">取消</el-button><el-button type="danger" @click="exportCodeToImgConfirm">确认</el-button></template></el-dialog>
</template><style lang="scss">
* {padding: 0;margin: 0;box-sizing: border-box;
}.container {width: 100vw;height: 100vh;display: flex;flex-direction: column;.tool-bar {height: 9rem;background-color: #282c34;border-bottom: 0.1rem solid gray;display: flex;flex-direction: column;align-items: center;justify-content: center;user-select: none;.row {width: 100%;flex: 1;display: flex;align-items: center;justify-content: center;}}.content-container {flex: 1;overflow: auto;display: flex;flex-direction: column;&::-webkit-scrollbar {width: 0;height: 0;}.md-editor-footer {display: none;}.cm-scroller {background-color: #282c34;}.editor-content {height: fit-content;border-bottom: 0.1rem solid gray;}.display-content {height: fit-content;border-bottom: 0.1rem solid gray;.md-editor-preview-wrapper {padding: 0;}.md-editor-code {margin: 0;}.md-editor-code-head {border-radius: 0 !important;}code {border-radius: 0 !important;white-space: pre-wrap;}}.input-content {flex: 1;background-color: #282c34;border-bottom: 0.1rem solid gray;}.result-content {flex: 1;background-color: #282c34;}}
}
</style>

后台核心代码

后台采用命令行运行代码,在Java、C、C++、C#,代码运行时会需要多步骤进行,目前采用的都是将代码写入到指定文件,然后采用指定命令运行绝对路径的文件,限制较大,后续考虑运行项目的形式,可以更加方便的解决文件编码问题以及代码运行问题

Java调用cmd运行代码工具类

package com.boot.util;import lombok.extern.slf4j.Slf4j;import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Date;import static com.boot.util.DefaultConfig.*;
import static com.boot.util.LanguageType.*;/*** @author bbyh* @date 2023/2/27 0027 15:10*/
@Slf4j
public class ExecUtil {public static String exec(String language, String codeText, String inputText) throws Exception {File codeTextInputFile = new File(LANGUAGE_INPUT_FILE_MAP.get(language));if (codeTextInputFile.exists()) {try (FileOutputStream outputStream = new FileOutputStream(codeTextInputFile)) {outputStream.write(codeText.getBytes(StandardCharsets.UTF_8));}}File inputTextInputFile = new File(INPUT_TEXT_PUT_FILE);if (inputTextInputFile.exists()) {try (FileOutputStream outputStream = new FileOutputStream(inputTextInputFile)) {outputStream.write(inputText.getBytes(StandardCharsets.UTF_8));}}if (judgeLinux()) {int exeCode = execLinux(language);logCodeTextRunLog(language, codeText, inputText, exeCode);} else if (judgeWindows()) {int exeCode = execWindows(language);logCodeTextRunLog(language, codeText, inputText, exeCode);}String[] outputFileNames = {ERROR_OUTPUT_FILE, OUTPUT_FILE};for (String outputFileName : outputFileNames) {File outputFile = new File(outputFileName);if (outputFile.exists()) {try (FileInputStream inputStream = new FileInputStream(outputFile)) {byte[] buf = new byte[1024 * 1024];int read = inputStream.read(buf);if (read >= 0) {String result = new String(buf, 0, read);String encoding = getEncoding(result);if (!"".equals(encoding)) {return new String(buf, 0, read, encoding);}}}}}return "";}private static void logCodeTextRunLog(String language, String codeText, String inputText, int exeCode) {log.info("运行时间:{}", new Date());log.info("编程语言:{}", language);log.info("运行代码:{}", codeText);log.info("运行输入:{}", inputText);log.info("运行结果:{}", exeCode);}private static int execLinux(String language) throws Exception {switch (language) {case JAVA:if (execLinuxCommand("javac " + JAVA_INPUT_FILE + " > " + OUTPUT_FILE + " 2> " + ERROR_OUTPUT_FILE) == 0) {int start = JAVA_INPUT_FILE.lastIndexOf("/") + 1;int end = JAVA_INPUT_FILE.lastIndexOf(".");String javaClassFileName = JAVA_INPUT_FILE.substring(start, end);return execLinuxCommand("java -classpath " + LINUX_PREFIX + " " + javaClassFileName + " < " + INPUT_TEXT_PUT_FILE + " > " + OUTPUT_FILE + " 2> " + ERROR_OUTPUT_FILE);}return 0;case PYTHON:return execLinuxCommand("python " + PYTHON_INPUT_FILE + " < " + INPUT_TEXT_PUT_FILE + " > " + OUTPUT_FILE + " 2> " + ERROR_OUTPUT_FILE);case JAVASCRIPT:return execLinuxCommand("node " + JAVASCRIPT_INPUT_FILE + " < " + INPUT_TEXT_PUT_FILE + " > " + OUTPUT_FILE + " 2> " + ERROR_OUTPUT_FILE);case C:if (execLinuxCommand("gcc " + C_INPUT_FILE + " -o " + LINUX_PREFIX + "a.exe > " + OUTPUT_FILE + " 2> " + ERROR_OUTPUT_FILE) == 0) {return execLinuxCommand(LINUX_PREFIX + "a.exe < " + INPUT_TEXT_PUT_FILE + " > " + OUTPUT_FILE + " 2> " + ERROR_OUTPUT_FILE);}return 0;case C_PLUS_PLUS:if (execLinuxCommand("g++ " + C_PLUS_PLUS_INPUT_FILE + " -o " + LINUX_PREFIX + "a.exe > " + OUTPUT_FILE + " 2> " + ERROR_OUTPUT_FILE) == 0) {return execLinuxCommand(LINUX_PREFIX + "a.exe < " + INPUT_TEXT_PUT_FILE + "> " + OUTPUT_FILE + " 2> " + ERROR_OUTPUT_FILE);}return 0;case C_SHARP:if (execLinuxCommand("csc /out:" + LINUX_PREFIX.replaceAll("/", "\\\\") + "a.exe "+ C_SHARP_INPUT_FILE.replaceAll("/", "\\\\") + " > " + OUTPUT_FILE + " 2> " + ERROR_OUTPUT_FILE) == 0) {return execLinuxCommand(LINUX_PREFIX + "a.exe < " + INPUT_TEXT_PUT_FILE + " > " + OUTPUT_FILE + " 2> " + ERROR_OUTPUT_FILE);}return 0;}return 0;}private static int execLinuxCommand(String command) throws Exception {ArrayList<String> commandList = new ArrayList<>();commandList.add("/bin/sh");commandList.add("-c");commandList.add(command);Process exec = Runtime.getRuntime().exec(commandList.toArray(new String[0]));return exec.waitFor();}private static int execWindows(String language) throws Exception {switch (language) {case JAVA:if (execWindowsCommand("javac " + JAVA_INPUT_FILE + " > " + OUTPUT_FILE + " 2> " + ERROR_OUTPUT_FILE) == 0) {int start = JAVA_INPUT_FILE.lastIndexOf("/") + 1;int end = JAVA_INPUT_FILE.lastIndexOf(".");String javaClassFileName = JAVA_INPUT_FILE.substring(start, end);return execWindowsCommand("java -classpath " + WINDOWS_PREFIX + " " + javaClassFileName + " < " + INPUT_TEXT_PUT_FILE + " > " + OUTPUT_FILE + " 2> " + ERROR_OUTPUT_FILE);}break;case PYTHON:return execWindowsCommand("python " + PYTHON_INPUT_FILE + " < " + INPUT_TEXT_PUT_FILE + " > " + OUTPUT_FILE + " 2> " + ERROR_OUTPUT_FILE);case JAVASCRIPT:return execWindowsCommand("node " + JAVASCRIPT_INPUT_FILE + " < " + INPUT_TEXT_PUT_FILE + " > " + OUTPUT_FILE + " 2> " + ERROR_OUTPUT_FILE);case C:if (execWindowsCommand("gcc " + C_INPUT_FILE + " -o " + WINDOWS_PREFIX + "a.exe > " + OUTPUT_FILE + " 2> " + ERROR_OUTPUT_FILE) == 0) {return execWindowsCommand(WINDOWS_PREFIX + "a.exe < " + INPUT_TEXT_PUT_FILE + " > " + OUTPUT_FILE + " 2> " + ERROR_OUTPUT_FILE);}return 0;case C_PLUS_PLUS:if (execWindowsCommand("g++ " + C_PLUS_PLUS_INPUT_FILE + " -o " + WINDOWS_PREFIX + "a.exe > " + OUTPUT_FILE + " 2> " + ERROR_OUTPUT_FILE) == 0) {return execWindowsCommand(WINDOWS_PREFIX + "a.exe < " + INPUT_TEXT_PUT_FILE + " > " + OUTPUT_FILE + " 2> " + ERROR_OUTPUT_FILE);}return 0;case C_SHARP:if (execWindowsCommand("csc /out:" + WINDOWS_PREFIX.replaceAll("/", "\\\\") + "a.exe "+ C_SHARP_INPUT_FILE.replaceAll("/", "\\\\") + " > " + OUTPUT_FILE + " 2> " + ERROR_OUTPUT_FILE) == 0) {return execWindowsCommand(WINDOWS_PREFIX + "a.exe < " + INPUT_TEXT_PUT_FILE + "> " + OUTPUT_FILE + " 2> " + ERROR_OUTPUT_FILE);}return 0;}return 0;}private static int execWindowsCommand(String command) throws Exception {Process exec = Runtime.getRuntime().exec("cmd /c " + command);return exec.waitFor();}public static Boolean judgeWindows() {return System.getProperty("os.name").toLowerCase().contains("windows");}public static Boolean judgeLinux() {return System.getProperty("os.name").toLowerCase().contains("linux");}public static String getEncoding(String str) throws Exception {String[] encodes = {"UTF-8", "GBK"};for (String encode : encodes) {if (str.equals(new String(str.getBytes(encode), encode))) {return encode;}}return "";}}

效果展示

运行Java代码
在这里插入图片描述

运行Python代码
在这里插入图片描述

运行JavaScript代码
在这里插入图片描述

运行C语言代码
在这里插入图片描述

运行C++代码
在这里插入图片描述

运行C#代码
在这里插入图片描述

将代码下载为图片
在这里插入图片描述

源码下载

在线代码编辑器

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1549731.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Cookie、Session、Token(JWT)还不懂?

Cookie、Session、Token&#xff08;JWT&#xff09; 三者的区别与用途&#xff01;如何进行身份认证&#xff0c;保持用户登录状态&#xff1f; Cookie、Session 和 Token 都是在 Web 开发中用于管理用户状态和进行身份认证的技术&#xff0c;它们之间有以下区别和用途&#…

一步步带你Linux内核编译与安装

Linux内核编译与安装 安装流程 #mermaid-svg-0PfY2uowOUJaN2Ov {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-0PfY2uowOUJaN2Ov .error-icon{fill:#552222;}#mermaid-svg-0PfY2uowOUJaN2Ov .error-text{fill:#5522…

地区环境保护支出数据(2007-2023年)

政府环境保护支出是指ZF在环境保护方面投入的CZ资金&#xff0c;用于自然生态保护、污染防治、环境监测与监管等多个领域&#xff0c;旨在改善环境质量、防范环境风险以及促进可持续发展 一、数据介绍 数据名称&#xff1a;地区环境保护支出数据 数据范围&#xff1a;中国31…

yakit使用教程(二,配置证书并进行抓包改包操作)

前文链接&#xff1a;yakit下载安装教程。 一&#xff0c;下载并配置证书。 点击mitm&#xff0c;在跳转后的页面点击高级配置。 点击证书下载。 点击下载到本地并打开&#xff08;建议下载到桌面&#xff09;。 在火狐浏览器下载并安装FoxyProxy&#xff0c;具体参数配置如上…

一文上手skywalking【上】

一、skywalking预览 1.1 skywalking 概述 ​ Apache SkyWalking, 适用于分布式系统的应用程序性能监控工具&#xff0c;专为微服务、云原生和基于容器的 &#xff08;Kubernetes&#xff09; 架构而设计。官方地址: https://skywalking.apache.org/ 适用于分布式系统的应用程…

Humans or LLMs as the Judge? A Study on Judgement Bias

文章目录 题目摘要引言相关作品论法官的偏见实验方案结果与讨论欺骗LLM法官结论 题目 人类还是LLMs作为裁判&#xff1f;判断偏差研究 论文地址&#xff1a;https://arxiv.org/pdf/2402.10669 摘要 采用人类和大型语言模型(LLM)作为评估LLM性能的评判者(也称为人类和LLM-as-a…

Java语法-类和对象之抽象类和接口

1.抽象类 1.1 抽象类的概念 一个类中没有足够的信息来描述一个具体的对象,这样的类就是抽象类 比如: 从图中我们可以看出,只有继承了的类,我们产生的实例,调用的draw方法都是他们本身重写的draw方法,不会调用父类Shape的draw()方法,因此我们可以不管父类里面的draw()方法里面的…

第十四届蓝桥杯真题Java c组A.求和(持续更新)

博客主页&#xff1a;音符犹如代码系列专栏&#xff1a;蓝桥杯关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ 【问题描述】 求1(含)至 20230408(含)中每个数的和。 【答案提交】 这是一道结…

24年下重庆事业单位考试报名超详细流程

&#x1f388;提交报考申请 考生通过重庆市人力资源和社会保障局官网&#xff08;rlsbj.cq.gov.cn&#xff09;“热点服务”中“人事考试网上报名”栏进行报名。报名时间为2024年8月12日9:00—8月17日9:00。 &#x1f388;网上缴费 资格初审合格后&#xff0c;考生应在2024年8…

flink设置保存点和恢复保存点

增加了hdfs package com.qyt;import org.apache.flink.api.java.functions.KeySelector; import org.apache.flink.api.java.tuple.Tuple2;import org.apache.flink.runtime.state.storage.FileSystemCheckpointStorage;import org.apache.flink.streaming.api.datastream.Dat…

精通推荐算法32:行为序列建模总结

1 行为序列建模总体架构 2 行为序列整体总结 用户行为序列建模是推荐算法中至关重要的一环&#xff0c;也是目前较为核心和前沿的研究方向。其主要分为短序列建模和长序列建模两大方向。短序列建模又主要分为池化和序列化两种方式&#xff0c;其中池化包括Sum-Pooling、Averag…

信道衰落的公式

对于天线&#xff1a; 对于天线的面积计算&#xff1a; 天线的接收功率密度&#xff1a; 天线的接收功率&#xff1a; 移动无线信道&#xff08;I&#xff09; (xidian.edu.cn)https://web.xidian.edu.cn/zma/files/20150710_153736.pdf 更加常用的考虑了额外的信道衰落pathlo…

甘肃辣椒油:舌尖上的热辣诱惑

&#x1f4a5;宝子们&#xff0c;今天必须要给你们安利甘肃食家巷的辣椒油&#x1f336;️&#xff01;✨甘肃辣椒油&#xff0c;那可是有着独特魅力的美食瑰宝&#x1f60d;。它以其鲜艳的色泽、浓郁的香气和醇厚的辣味&#xff0c;瞬间点燃你的味蕾&#x1f525;。&#x1f3…

《Spring Boot应用进阶:打造优雅的错误处理机制与全局异常拦截器》

文章目录 自定义异常类AppException封装业务有关的枚举类AppExceptionCodeMsg全局异常拦截器Handler响应类模板Resp案例展示 || Demo项目结构pom依赖DemoController实际执行结果 Demo案例Git地址 | Gitee 本文主要介绍自己在工作中在处理抛出异常类和封装响应类处理的模板总结。…

【matlab画多纵坐标图像】

一 、什么是多纵坐标图像 多纵坐标图像是一种在同一个坐标系中&#xff0c;使用多个纵坐标轴来表示不同的数据指标的图像。在多纵坐标图中&#xff0c;每个纵坐标轴可以有不同的刻度和单位&#xff0c;用于表示不同的数据范围。这样可以方便地比较不同指标的变化趋势&#xff0…

【C语言】单片机map表详细解析

1、RO Size、RW Size、ROM Size分别是什么 首先将map文件翻到最下面&#xff0c;可以看到 1.1 RO Size&#xff1a;只读段 Code&#xff1a;程序的代码部分&#xff08;也就是 .text 段&#xff09;&#xff0c;它存放了程序的指令和可执行代码。 RO Data&#xff1a;只读…

供应链 | 顶刊POMS论文精读:交易成本经济学(TCE)——供应链效率理论

编者按 供应链效率提升指南&#xff1a;不可不知的TCE理论视角 本文为Production and Operations Management 期刊论文&#xff0c;原文信息&#xff1a; Ketokivi, M., & Mahoney, J. T. (2020). Transaction cost economics as a theory of supply chain efficiency. …

自然资源部最新Nature正刊!!!

2024年8月21日&#xff0c;国际顶级期刊《Nature》发表了自然资源部第二海洋研究所李家彪院士为通讯作者&#xff0c;张涛为第一作者的论文“超慢速扩张加克洋中脊的高变化岩浆增生”。这一成果颠覆了国际海洋学术界半个多世纪以来一直认为的超慢速扩张洋中脊岩浆供给极度贫瘠的…

9.28 Qt界面

#include "widget.h"Widget::Widget(QWidget *parent): QWidget(parent) {this->setWindowTitle("Plane");this->setWindowIcon(QIcon("C:/Users/EDY/Desktop/递送发送.png"));QPushButton *btn1new QPushButton;this->setFixedSize(64…

[SAP ABAP] 锁对象

在SAP中使用锁对象&#xff0c;用于避免在数据库中插入或更改数据时出现不一致的情况 1.创建锁对象 数据准备 学校表(ZDBT_SCH_437) 使用事务码SE11创建锁对象 点击"锁对象"单选按钮&#xff0c;输入以E开头的锁定对象的名称&#xff0c;然后点击创建按钮 锁对象名…