You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

IdeProject.vue 43 kB

3 years ago
3 years ago
3 years ago
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412
  1. <template>
  2. <div style="overflow: hidden">
  3. <div v-if="params.type === 'ide'">
  4. <div class="ide-header">
  5. <span>
  6. <svg class="icon ide-header-svg" aria-hidden="true">
  7. <use xlink:href="#icon-wenjianbeifen"></use>
  8. </svg>
  9. {{ `${params.owner}/${params.project}` }}
  10. </span>
  11. <i class="el-icon-switch-button" @click="handleBack" />
  12. </div>
  13. <div style="display: flex">
  14. <div class="menu-left">
  15. <el-menu :default-active="activeKey" class="menu-left-drag-item-drag" background-color="#F5F5F5" text-color="#7A7A7B" active-text-color="#000" @select="handleselect">
  16. <el-menu-item index="1" style="line-height: 20px;height: 90px;padding: 20px 22px 46px 23px;" :class="{ activeBack: isActiveStatus }">
  17. <!-- <img class="menu-left-drag-img" :src="isActiveStatus ? code1 : code2" alt="" />-->
  18. <svg class="icon menu-left-drag-svg" aria-hidden="true">
  19. <use xlink:href="#icon-daima1"></use>
  20. </svg>
  21. <div slot="title">代码</div>
  22. </el-menu-item>
  23. <el-menu-item index="2" style="line-height: 20px;height: 90px;background-color: #F5F5F5;padding: 20px 22px 46px 23px;" :class="{ activeBack: activeKey === '2' }">
  24. <!-- <img class="menu-left-drag-img" :src="isActiveStatus ? submitLog2 : submitLog1" alt="" />-->
  25. <svg class="icon menu-left-drag-svg" aria-hidden="true">
  26. <use xlink:href="#icon-tijiao"></use>
  27. </svg>
  28. <div slot="title">提交</div>
  29. </el-menu-item>
  30. </el-menu>
  31. </div>
  32. <div ref="box" class="box">
  33. <div class="inlineBlock leftPaneBase" :style="{ width: leftPanelWidth }">
  34. <div class="leftPaneBase-submit">
  35. <!-- <img class="mr5" :src="isActiveStatus ? warehouse : submit" alt="" />-->
  36. {{ isActiveStatus ? "代码仓库" : "提交" }}
  37. </div>
  38. <VueTree v-show="isActiveStatus" :tree-list-data="treeData" :file-info-params="fileInfoParams"
  39. @handleChangFile="handleChangFile" @deleteNode="handleNode" @handleAddNode="handleAddNode"
  40. @handleDeleteAddNode="handleDeleteAddNode" @handleDeleteOldNode="handleDeleteOldNode" />
  41. <div v-show="!isActiveStatus && inCludeSub" class="leftPaneBase-wrap">
  42. <div class="leftPaneBase-wrap-change">
  43. <span style="font-weight: 400;">更改</span>
  44. <el-tooltip class="item" effect="dark" content="放弃所有更改" placement="bottom-end">
  45. <!-- <img class="leftPaneBase-wrap-change-img" :src="abandon" alt="" @click="handleResetAll()" />-->
  46. <svg class="icon leftPaneBase-wrap-change-img leftPaneBase-wrap-change-svg " aria-hidden="true" @click="handleResetAll()" >
  47. <use xlink:href="#icon-zhongzhi3"></use>
  48. </svg>
  49. </el-tooltip>
  50. </div>
  51. </div>
  52. <div class="leftPaneBase-wrap" v-show="!isActiveStatus && inCludeSub">
  53. <div class="leftPaneBase-wrap-fileName">
  54. <div v-show="!submitAarry.length" class="no-commit">
  55. 当前没有可提交的文件
  56. </div>
  57. <div v-show="(!!submitAarry.length && item.type === 'blob')" v-for="item in submitAarry" :key="item.sha"
  58. class="leftPaneBase-wrap-fileName-item">
  59. <span @click="handleDiff(item)">{{ item.name }}</span>
  60. <el-tooltip class="item" effect="dark" content="放弃更改" placement="bottom-end">
  61. <!-- <img :src="abandon" alt="" @click="handleload(item)" />-->
  62. <svg class="icon leftPaneBase-wrap-fileName-item-img leftPaneBase-wrap-change-svg" @click="handleload(item)" aria-hidden="true">
  63. <use xlink:href="#icon-zhongzhi3"></use>
  64. </svg>
  65. </el-tooltip>
  66. </div>
  67. </div>
  68. </div>
  69. <div style="width: 100%;padding: 0 20px;" >
  70. <div style="border-bottom: 1px solid #b1bacd;"></div>
  71. </div>
  72. <div v-show="!isActiveStatus && inCludeSub" class="leftPaneBase-wrap">
  73. <div class="leftPaneBase-wrap-info">提交信息</div>
  74. <el-input :disabled="!submitAarry.length" v-model="textContent" class="leftPaneBase-wrap-input"
  75. type="textarea" :rows="10" placeholder="请输入提交信息" />
  76. <div style="width: 100%; padding: 0 20px;">
  77. <el-button :disabled="!submitAarry.length" v-loading="subLoading" type="primary"
  78. element-loading-spinner="el-icon-loading" element-loading-background="rgba(0, 0, 0, 0.8)"
  79. class="leftPaneBase-wrap-infoSubmit" @click="handleSubmit">
  80. 提交
  81. </el-button>
  82. </div>
  83. </div>
  84. </div>
  85. <!-- <img :src="drag" alt="" title="收缩侧边栏" class="resize" /> -->
  86. <div class="resize" title="收缩侧边栏"></div>
  87. <div class="inlineBlock mid">
  88. <div class="mid-header">
  89. <span>{{ isDiff ? "" : fileInfoParams.path }}</span>
  90. <div>
  91. <span v-if="fileInfo.fileType === 'ipynb' && !hideNbView " style="cursor:pointer;margin-right:20px" @click="handleEdit">
  92. 修改
  93. <i class="el-icon-edit" />
  94. </span>
  95. <span v-if="fileInfo.fileType === 'ipynb' && hideNbView " style="cursor:pointer;margin-right:20px" @click="handleEdit">
  96. 预览
  97. <i class="el-icon-view" />
  98. </span>
  99. <span style="cursor:pointer" @click="handleSetting">设置<i class="el-icon-s-tools" /></span>
  100. </div>
  101. </div>
  102. <!-- <codemirror /> -->
  103. <div v-show="!fileInfoParams.filePath" class="empty-tip">
  104. <img width="200" :src="empty" />
  105. 请在左侧文件树中选择一个文件,编辑后即可提交你的修改
  106. </div>
  107. <div v-if="containerReload">
  108. <div class="showImg" v-if="fileInfo.fileType === 'image'" >
  109. <img :src="fileInfo.download_url" />
  110. </div>
  111. <div class="showImg" v-else-if="fileInfo.fileType === 'office'" >
  112. <el-button type="primary" @click="downloadUrl(fileInfo.download_url)"><a style="color:white" :href="fileType && fileType.download_url">下载</a></el-button>
  113. </div>
  114. <div class="showPdf" v-else-if="fileInfo.fileType === 'pdf'" >
  115. <embed :src="fileInfo.download_url" />
  116. </div>
  117. <div class="showImg" v-else-if="fileInfo.download_url && fileInfo.fileType !== 'txt' && fileInfo.fileType !== 'ipynb'">
  118. <el-button type="primary" @click="downloadUrl(fileInfo.download_url)"><a style="color:white" :href="fileType && fileType.download_url">下载</a></el-button>
  119. </div>
  120. <div :class="(fileInfo.fileType === 'txt' || fileInfo.fileType === 'ipynb') ? '' : 'hides'">
  121. <iframe v-if="(fileInfo.fileType === 'ipynb' && !hideNbView && !isDiff)" src="/js/nbview/index.html" id="nbview" @load="loadFrame()"></iframe>
  122. <monaco ref="monaco" v-loading="monacoLoading" element-loading-text="拼命加载中"
  123. element-loading-spinner="el-icon-loading" element-loading-background="rgba(255, 255, 255, 0.8)"
  124. :opts="opts" :is-diff="isDiff" :monaca-value="monacaValue" @handleSave="handleSave" />
  125. </div>
  126. </div>
  127. </div>
  128. </div>
  129. <el-drawer style="height: calc(100vh - 94px); margin-top: 94px" class="drawer-wrap"
  130. :visible.sync="drawerVisible" direction="rtl" destroy-on-close size="270" :show-close="false"
  131. :with-header="false" :modal="false">
  132. <div class="drawer-section">
  133. <div class="drawer-section-style" style="padding-bottom:10px;">
  134. <div class="code-fast">代码格式</div>
  135. <div class="drawer-section-stydrawer-sectionle-wrap">
  136. <span class="drawer-wrap-span">显示模式</span>
  137. <el-select v-model="opts.theme" size="mini" placeholder="请选择" @change="handleChangeModelOptions">
  138. <el-option v-for="item in modeOptions" :key="item.value" :label="item.label" :value="item.value" />
  139. </el-select>
  140. </div>
  141. <div class="drawer-section-style-wrap">
  142. <span class="drawer-wrap-span">字体大小</span>
  143. <el-select v-model="opts.fontSize" size="mini" placeholder="请选择" @change="handleChangeFontSizeOptions">
  144. <el-option v-for="item in fontSizeOptions" :key="item.value" :label="item.label" :value="item.value" />
  145. </el-select>
  146. </div>
  147. <!-- <div class="drawer-section-style-wrap">
  148. <span>Tab转换</span>
  149. <el-switch v-model="switchValue" active-color="#2185D0" inactive-color="#858585" />
  150. </div> -->
  151. </div>
  152. <div class="drawer-fast">
  153. <div class="code-fast">快捷键</div>
  154. <div class="drawer-fast-flex">
  155. <span class="drawer-wrap-span">保存代码</span><span class="drawer-wrap-span2">Ctrl + S</span>
  156. </div>
  157. <div class="drawer-fast-flex">
  158. <span class="drawer-wrap-span">唤出快捷键列表</span><span class="drawer-wrap-span2">F1/Alt + F1</span>
  159. </div>
  160. <div class="drawer-fast-flex">
  161. <span class="drawer-wrap-span">左右缩进</span><span class="drawer-wrap-span2">Ctrl + ]/[</span>
  162. </div>
  163. </div>
  164. </div>
  165. </el-drawer>
  166. </div>
  167. </div>
  168. <div v-else v-loading="loading" class="vscode-loading-wrap" element-loading-text="拼命加载中"
  169. element-loading-spinner="el-icon-loading">
  170. <div class="vscode-header">
  171. <span>{{ `${params.owner}/${params.project}` }}</span>
  172. <div class="vscode-header-right">
  173. <div class="color inlineBlock mr40">
  174. <i class="el-icon-time" />
  175. <span class="vscode-header-right-text">{{ count }}</span>
  176. </div>
  177. <dvi class="inlineBlock mr40 cspointe">
  178. <i class="el-icon-s-cooperation" />
  179. <span class="vscode-header-right-text" @click="handleReset">重置环境</span>
  180. </dvi>
  181. <i class="el-icon-switch-button cspointe" @click="handleBack" />
  182. </div>
  183. </div>
  184. <div>
  185. <iframe v-if="headerParams.url" class="iframe-wrap" :src="headerParams.url" />
  186. </div>
  187. </div>
  188. </div>
  189. </template>
  190. <script>
  191. // import VueTreeList from './VueTreeList.vue';
  192. const API = "http://121.40.129.71:48991";
  193. import VueTree from "./vueTree.vue";
  194. import {
  195. matterTree,
  196. RecurveQuery,
  197. RecurveQueryDelete,
  198. RecurveAddNode,
  199. RecurveUpdateValue,
  200. uniqueArray,
  201. } from "../utils.js";
  202. import monaco from "./monacoeditor.vue";
  203. import code1 from "../../../public/images/code1.png";
  204. import empty from "../../../public/img/empty.png";
  205. import code2 from "../../../public/images/code2.png";
  206. import submitLog2 from "../../../public/images/submitLog2.png";
  207. import submitLog1 from "../../../public/images/submitLog1.png";
  208. import abandon from "../../../public/images/abandon.png";
  209. import warehouse from "../../../public/images/warehouse.png";
  210. import submit from "../../../public/images/submit.png";
  211. import drag from "../../../public/images/drag.png";
  212. import {
  213. init,
  214. add,
  215. readAll,
  216. readByMainKey,
  217. deleteDB,
  218. update,
  219. remove,
  220. } from "./db.js";
  221. export default {
  222. name: "IdeProject",
  223. components: {
  224. // codemirror,
  225. monaco,
  226. // VueTreeList,
  227. VueTree,
  228. },
  229. data() {
  230. return {
  231. activeKey: "1",
  232. drawerVisible: false,
  233. fileInfo: {},
  234. // 图片
  235. code1,
  236. code2,
  237. empty,
  238. submitLog1,
  239. submitLog2,
  240. abandon,
  241. warehouse,
  242. submit,
  243. drag,
  244. // 图片
  245. leftPanelWidth: "300px",
  246. modeOptions: [
  247. { label: "light", value: "vs" },
  248. { label: "dark", value: "vs-dark" },
  249. ],
  250. fontSizeOptions: [
  251. { label: "14px", value: 14 },
  252. { label: "16px", value: 16 },
  253. { label: "18px", value: 18 },
  254. { label: "20px", value: 20 },
  255. { label: "22px", value: 22 },
  256. ],
  257. textContent: "", // 文本域输入框的值
  258. monacaValue: "", // monaca编辑器的值
  259. fileInfoParams: {}, // 所点击的文件以及参数
  260. monacoLoading: false,
  261. sets: {
  262. language: {
  263. apex: "apex",
  264. azcli: "azcli",
  265. bat: "bat",
  266. c: "c",
  267. clojure: "clojure",
  268. coffeescript: "coffeescript",
  269. cpp: "cpp",
  270. csharp: "csharp",
  271. csp: "csp",
  272. css: "css",
  273. dockerfile: "dockerfile",
  274. fsharp: "fsharp",
  275. go: "go",
  276. graphql: "graphql",
  277. handlebars: "handlebars",
  278. html: "html",
  279. ini: "ini",
  280. java: "java",
  281. javascript: "javascript",
  282. json: "json",
  283. kotlin: "kotlin",
  284. less: "less",
  285. lua: "lua",
  286. markdown: "markdown",
  287. msdax: "msdax",
  288. mysql: "mysql",
  289. "objective-c": "objective-c",
  290. pascal: "pascal",
  291. perl: "perl",
  292. pgsql: "pgsql",
  293. php: "php",
  294. plaintext: "plaintext",
  295. postiats: "postiats",
  296. powerquery: "powerquery",
  297. powershell: "powershell",
  298. pug: "pug",
  299. python: "python",
  300. r: "r",
  301. razor: "razor",
  302. redis: "redis",
  303. redshift: "redshift",
  304. ruby: "ruby",
  305. rust: "rust",
  306. sb: "sb",
  307. scheme: "scheme",
  308. scss: "scss",
  309. shell: "shell",
  310. sol: "sol",
  311. sql: "sql",
  312. st: "st",
  313. swift: "swift",
  314. tcl: "tcl",
  315. typescript: "typescript",
  316. vb: "vb",
  317. xml: "xml",
  318. yaml: "yaml",
  319. },
  320. theme: {
  321. vs: "vs",
  322. "vs-dark": "vs-dark",
  323. "hc-black": "hc-black",
  324. },
  325. colorDecorators: true,
  326. comments: {
  327. ignoreEmptyLines: true, // 插入行注释时忽略空行。默认为真。
  328. insertSpace: true, // 在行注释标记之后和块注释标记内插入一个空格。默认为真。
  329. },
  330. },
  331. opts: {
  332. value: "",
  333. diffData: {},
  334. readOnly: false, // 是否可编辑
  335. language: "", // 语言类型
  336. theme: "vs", // 编辑器主题
  337. selectOnLineNumbers: true,
  338. roundedSelection: false,
  339. // readOnly: this.readOnly, // 只读
  340. cursorStyle: "line", // 光标样式
  341. automaticLayout: false, // 自动布局
  342. glyphMargin: true, // 字形边缘
  343. useTabStops: false,
  344. fontSize: 14, // 字体大小
  345. autoIndent: false, // 自动布局
  346. },
  347. hideNbView:false,
  348. isDiff: false,
  349. inlineDiff: false,
  350. containerReload: true,
  351. switchValue: false,
  352. loading: true,
  353. treeData: [], // 子组件的数据
  354. pathname: "", // 编辑文件的文件名
  355. submitAarry: [], // 提交时候数组数据
  356. subLoading: false,
  357. treeRootData: [], // 文件树的节点
  358. /** 以下为vscode的初始变量 */
  359. params: this.$route.query, // 从项目列表进来 type === ide | vscode 前者是编辑 后者是嵌套
  360. headerParams: {
  361. remainingTime: 0,
  362. url: "",
  363. }, // 包含src的url + 倒计时的remainingTime
  364. count: "00:00:00",
  365. timer: null,
  366. // eslint-disable-next-line semi
  367. };
  368. },
  369. computed: {
  370. isActiveStatus() {
  371. // 计算当前的activeKey为提交 还是 代码界面
  372. return this.activeKey === "1";
  373. },
  374. inCludeSub() {
  375. // 计算提交界面的数据是否有数据
  376. return true;
  377. },
  378. },
  379. mounted() {
  380. if (this.params.type === "vscode") {
  381. this.getVscodeData();
  382. } else {
  383. this.getCodeTree();
  384. }
  385. init({
  386. // 数据库名称
  387. dbName: this.params.project,
  388. // 数据表 数组 如果要创建多个表,则写多个即可
  389. tableList: [
  390. {
  391. // 表名
  392. tableName: "git",
  393. // 主键
  394. keyPath: "name",
  395. // 对应表的其他属性
  396. // attr:{
  397. // autoIncrement:true, //是否自增
  398. // },
  399. indexName: "index", // 索引 不建议使用 因为使用索引 当前表必须有数据否则直接报错
  400. // unique:false // 对应索引是否唯一
  401. },
  402. ],
  403. });
  404. this.dragControllerDiv();
  405. },
  406. provide() {
  407. return {
  408. reload: this.reload,
  409. };
  410. },
  411. methods: {
  412. handleDiff(data) {
  413. this.fileInfoParams = data;
  414. this.fileInfo = data;
  415. console.log("handleDiff:", this.fileInfoParams);
  416. this.$refs.monaco.setDiff(data.oldcontent, data.newContent);
  417. },
  418. downloadUrl(string){
  419. window.location.href = string;
  420. },
  421. // 更新提交界面的数据状态
  422. treeNodeModify(data) {
  423. const getData = async () => {
  424. const data = await readAll("git");
  425. console.log("data:", data);
  426. if (data && Array.isArray(data)) {
  427. this.submitAarry = data
  428. .filter(
  429. (name) =>
  430. name.name !== "treeData" && name.name !== "undefined" && name.d
  431. )
  432. .map((item) => item.d);
  433. console.log("this.submitAarry:", this.submitAarry);
  434. }
  435. };
  436. getData();
  437. // const newSubArray = [];
  438. // function findModifyObj(data) {
  439. // data.forEach((item) => {
  440. // if (item.isLeaf && item.operation) {
  441. // newSubArray.push(item);
  442. // } else {
  443. // findModifyObj(item.children);
  444. // }
  445. // });
  446. // }
  447. // findModifyObj(data);
  448. },
  449. // 新增文件
  450. handleAddNode(treeD, filePath) {
  451. this.treeRootData = RecurveAddNode(this.treeRootData, treeD, filePath);
  452. this.updateData(treeD);
  453. setTimeout(async () => {
  454. await add({
  455. tableName: "git",
  456. data: { name: "treeData", data: [...this.treeRootData] },
  457. });
  458. this.treeNodeModify(this.treeRootData);
  459. })
  460. },
  461. updateData(d) {
  462. // const k = await readByMainKey({ tableName: "git", key: "treeData" });
  463. // const d = { ...k, ...data };
  464. // this.treeData = matterTree(d.tree);
  465. // this.treeRootData = JSON.parse(JSON.stringify(this.treeData));
  466. console.log("updateData:", d);
  467. add({
  468. tableName: "git",
  469. data: { name: encodeURI(d.filePath), d },
  470. });
  471. },
  472. loadFrame(){
  473. document.getElementById("nbview").contentWindow.postMessage(this.fileInfo, '*');
  474. },
  475. // 删除新增的文件
  476. handleDeleteAddNode(valueNode) {
  477. this.treeRootData = RecurveQueryDelete(
  478. this.treeRootData,
  479. valueNode.filePath
  480. );
  481. this.treeNodeModify(this.treeRootData);
  482. },
  483. // 删除已有的文件
  484. handleDeleteOldNode(valueNode) {
  485. this.treeRootData = RecurveQuery(this.treeRootData, valueNode.filePath);
  486. this.treeNodeModify(this.treeRootData);
  487. },
  488. clearAllData() {
  489. const clear = async () => {
  490. const data = await readAll("git");
  491. if (data && Array.isArray(data)) {
  492. this.fileInfoParams.filePath = null
  493. this.submitAarry = data.map((item) => {
  494. // if (item.d) {
  495. remove({
  496. tableName: "git",
  497. key: encodeURI(item.name),
  498. });
  499. // }
  500. });
  501. console.log("this.submitAarry:", this.submitAarry);
  502. }
  503. setTimeout(() => {
  504. this.treeNodeModify();
  505. }, 200);
  506. };
  507. clear();
  508. },
  509. // 放弃所有更改
  510. handleResetAll() {
  511. this.$confirm(`确定要放弃所有文件的更改吗?`, "提示", {
  512. confirmButtonText: "确定",
  513. cancelButtonText: "取消",
  514. type: "warning",
  515. })
  516. .then(async () => {
  517. // this.handleFileInfo(params);
  518. console.log("this2222222:", this.clearAllData, this)
  519. this.clearAllData();
  520. this.isDiff = false;
  521. this.$refs.monaco.setCloseDiff(false);
  522. })
  523. .catch(() => {
  524. console.log("取消成功");
  525. });
  526. },
  527. handleEdit(){
  528. const value = this.$refs.monaco.getVal();
  529. this.fileInfo.newContent = value;
  530. this.hideNbView = !this.hideNbView
  531. },
  532. // 放弃单个的更改---逻辑未处理
  533. handleload(value) {
  534. console.log("value", value);
  535. this.$confirm(`确定要放弃 ${value.path} 中的更改吗?`, "提示", {
  536. confirmButtonText: "确定",
  537. cancelButtonText: "取消",
  538. type: "warning",
  539. })
  540. .then(() => {
  541. // this.handleFileInfo(params);
  542. // if (value.sha) {
  543. remove({
  544. tableName: "git",
  545. key: encodeURI(value.path),
  546. });
  547. this.treeNodeModify();
  548. // }
  549. })
  550. .catch(() => {
  551. console.log("取消成功");
  552. });
  553. },
  554. // 提交事件。 接口地址:https://www.apifox.cn/apidoc/shared-906bc1af-5c25-4b9d-b0e0-4d1176ffe4a9/api-30499442。operation为update/add/delete三种
  555. async handleSubmit() {
  556. if (!this.textContent.trim())
  557. return this.$message.warning("提交信息不能为空!");
  558. try {
  559. this.subLoading = true;
  560. await this.$axios
  561. .post(
  562. `/api/v1/repos/${this.params.owner}/${this.params.project}/contents/commit`,
  563. {
  564. files: this.submitAarry?.filter(item => item.type === "blob")?.map((item) => {
  565. // item.content = Buffer.from(item.newContent).toString("base64");
  566. // item.operation = "update";
  567. console.log("tem.newContent:",item.newContent,item)
  568. return {
  569. filePath: item.path,
  570. content: Buffer.from(item.newContent).toString("base64"),
  571. operation: item.sha ? "update" : "add",
  572. };
  573. }),
  574. msg: this.textContent,
  575. }
  576. )
  577. .then(({ status }) => {
  578. if (status === "200" || status === 200) {
  579. this.subLoading = false;
  580. this.submitAarry = []; // 提交的列表
  581. this.$message.success("提交成功!");
  582. this.textContent = "";
  583. this.clearAllData();
  584. this.getCodeTree();
  585. }
  586. });
  587. } catch (error) {
  588. this.subLoading = false;
  589. console.log("error", error);
  590. }
  591. },
  592. // 演示
  593. async handleReset() {
  594. this.$confirm(`确定要重置环境吗?`, "提示", {
  595. confirmButtonText: "确定",
  596. cancelButtonText: "取消",
  597. type: "warning",
  598. })
  599. .then(async () => {
  600. this.loading = true
  601. this.headerParams = {}
  602. await this.$axios
  603. .post(`${API}/vscode/delete`, {
  604. projectId: this.params.project,
  605. userId: this.params.owner,
  606. })
  607. .then(({ status, data: { data } }) => {
  608. if (status === "200" || status === 200) {
  609. this.getVscodeData();
  610. } else {
  611. this.$message({
  612. message: '重置环境失败',
  613. type: 'warning'
  614. });
  615. }
  616. });
  617. })
  618. .catch(() => {
  619. console.log("取消成功");
  620. });
  621. },
  622. // 重置环境
  623. async handleReset() {
  624. this.$confirm(`确定要重置环境吗?`, "提示", {
  625. confirmButtonText: "确定",
  626. cancelButtonText: "取消",
  627. type: "warning",
  628. })
  629. .then(async () => {
  630. this.loading = true
  631. this.headerParams = {}
  632. await this.$axios
  633. .post(`${API}/vscode/delete`, {
  634. projectId: this.params.project,
  635. userId: this.params.owner,
  636. })
  637. .then(({ status, data: { data } }) => {
  638. if (status === "200" || status === 200) {
  639. this.getVscodeData();
  640. } else {
  641. this.$message({
  642. message: '重置环境失败',
  643. type: 'warning'
  644. });
  645. }
  646. });
  647. })
  648. .catch(() => {
  649. console.log("取消成功");
  650. });
  651. },
  652. // 返回按钮
  653. handleBack() {
  654. // this.$router.go(-1);
  655. this.$confirm(`确定要退出编辑吗?`, "提示", {
  656. confirmButtonText: "确定",
  657. cancelButtonText: "取消",
  658. type: "warning",
  659. })
  660. .then(async () => {
  661. window.location.href = `/${this.params.owner}/${this.params.project}`
  662. })
  663. .catch(() => {
  664. console.log("取消成功");
  665. });
  666. },
  667. // 获取vscode界面的接口
  668. async getVscodeData() {
  669. try {
  670. await this.$axios
  671. .post(`http://121.40.129.71:48991/vscode/getVscode`, {
  672. projectId: this.params.project,
  673. userId: this.params.owner,
  674. containers:
  675. "W3siaW1hZ2UiOiJ2c2NvZGUtd3c6djEuMCIsImNwdUxpbWl0IjoyLjAsImNwdVJlcXVlc3QiOjAuMywibWVtb3J5TGltaXQiOiIyMDQ4TSIsIm1lbW9yeVJlcXVlc3QiOiIxMDI0TSIsInJlc291cmNlTGltaXQiOiIxMDAwMEsiLCJzdGFydFRpbWUiOjIwMCwidHlwZSI6Im1haW4ifV0K",
  676. tpiGitURL:
  677. this.params.git,
  678. })
  679. .then(({ status, data: { data } }) => {
  680. if (status === "200" || status === 200) {
  681. this.loading = false;
  682. this.headerParams = data[0];
  683. this.Time();
  684. }
  685. });
  686. } catch (error) {
  687. console.log("获取vscode配置失败", error);
  688. }
  689. },
  690. handleNode(arr = []) {
  691. this.submitAarry = this.submitAarry.concat(arr);
  692. },
  693. // 获取组件树的接口
  694. async getCodeTree() {
  695. try {
  696. await this.$axios
  697. .get(
  698. `/api/v1/repos/${this.params.owner}/${this.params.project}/git/codes/head`,
  699. {
  700. headers: {
  701. Authorization: "token 3551a6fb122b0278133963474fcf18bfeef8baba",
  702. },
  703. }
  704. )
  705. .then(async ({ status, data }) => {
  706. if (status === "200" || status === 200) {
  707. const k = await readByMainKey({
  708. tableName: "git",
  709. key: "treeData",
  710. });
  711. const d = uniqueArray(k.data || [], data.tree);
  712. this.treeData = matterTree(d);
  713. this.treeRootData = JSON.parse(JSON.stringify(this.treeData));
  714. add({
  715. tableName: "git",
  716. data: { name: "treeData", data: d },
  717. });
  718. this.treeNodeModify();
  719. }
  720. });
  721. } catch (error) {
  722. console.log("获取vscode配置失败", error);
  723. }
  724. },
  725. // 点击组件树触发的父组件方法。目前思路。
  726. // ①如果是新增的文件,点击文件设置monaco编辑器内容为空
  727. // ②如果是已经存在的文件,点击文件调取接口 this.handleFileInfo
  728. //
  729. handleChangFile(params, treeData) {
  730. this.hideNbView = true;
  731. const getContent = async () => {
  732. const k = await readByMainKey({
  733. tableName: "git",
  734. key: encodeURI(params.filePath),
  735. });
  736. console.log("handleChangFile", treeData, params, k.d);
  737. if (k.d) {
  738. this.fileInfo = k.d;
  739. this.monacaValue = k.d.newContent;
  740. this.$refs.monaco.setLanguage(k.d.language)
  741. } else if (params.sha) {
  742. this.handleFileInfo(params);
  743. } else {
  744. this.monacaValue = "";
  745. }
  746. };
  747. this.fileInfoParams = params;
  748. getContent();
  749. // const editorGetValue = Buffer.from(
  750. // `${this.$refs.monaco.getVal()}`
  751. // ).toString("base64"); // 当前编辑器的值
  752. // console.log("handleChangFile:",params,treeData)
  753. // const BufferUtf = this.monacaValue; // 当前文件的值
  754. // if (params.operation === "add") {
  755. // // 是新增并且还没有编辑
  756. // this.monacaValue = params.oldContent ? params.oldContent : "";
  757. // this.fileInfoParams = params;
  758. // this.pathname = params.name;
  759. // } else if (params.sha && !params.oldContent) {
  760. // console.log("treeData", treeData);
  761. // this.handleFileInfo(params);
  762. // } else if (editorGetValue && BufferUtf && editorGetValue !== BufferUtf) {
  763. // // 当前编辑器的内容是否原有内容一致
  764. // this.$confirm(
  765. // `当前${this.fileInfoParams.name}文件未保存, 是否继续?`,
  766. // "提示",
  767. // {
  768. // confirmButtonText: "确定",
  769. // cancelButtonText: "取消",
  770. // type: "warning",
  771. // }
  772. // )
  773. // .then(() => {
  774. // this.handleFileInfo(params);
  775. // })
  776. // .catch(() => {
  777. // console.log("取消成功");
  778. // });
  779. // }
  780. },
  781. // 获取文件的内容
  782. async handleFileInfo(params) {
  783. try {
  784. this.monacoLoading = true;
  785. await this.$axios
  786. .get(
  787. `/api/v1/repos/${this.params.owner}/${this.params.project}/contents/${params.path}`
  788. )
  789. .then(({ status, data }) => {
  790. if (status === "200" || status === 200) {
  791. console.log("data:", data, data.language)
  792. this.fileInfo = {...data};
  793. this.monacoLoading = false;
  794. params.oldcontent = data.content;
  795. this.fileInfoParams = params;
  796. this.pathname = data.name;
  797. this.opts.language = data.language
  798. this.$refs.monaco.setLanguage(data.language)
  799. this.monacaValue = data.content;
  800. }
  801. });
  802. } catch (error) {
  803. this.monacoLoading = false;
  804. console.log("获取文件信息失败", error);
  805. }
  806. },
  807. // 提交/代码界面按钮切换事件
  808. handleselect(value) {
  809. this.hideNbView = true;
  810. this.fileInfoParams = {};
  811. this.diffData = {};
  812. this.isDiff = value == 1 ? false : true;
  813. this.$refs.monaco.setCloseDiff(true);
  814. this.activeKey = value;
  815. },
  816. // 中间图标的拖拽
  817. dragControllerDiv() {
  818. const resize = document.getElementsByClassName("resize");
  819. const left = document.getElementsByClassName("leftPaneBase");
  820. const mid = document.getElementsByClassName("mid");
  821. const box = document.getElementsByClassName("box");
  822. for (let i = 0; i < resize.length; i++) {
  823. // 鼠标按下事件
  824. resize[i].onmousedown = (e) => {
  825. //颜色改变提醒
  826. // resize[i].style.background = '#818181';
  827. var startX = e.clientX ;
  828. resize[i].left = resize[i].offsetLeft ;
  829. // 鼠标拖动事件
  830. document.onmousemove = function (e) {
  831. var endX = e.clientX;
  832. var moveLen = resize[i].left + (endX - startX) - 60; // (endx-startx)=移动的距离。resize[i].left+移动的距离=左边区域最后的宽度
  833. var maxT = box[i].clientWidth - resize[i].offsetWidth; // 容器宽度 - 左边区域的宽度 = 右边区域的宽度
  834. if (moveLen < 132) moveLen = 132; // 左边区域的最小宽度为32px
  835. // if (moveLen > maxT - 250) moveLen = maxT - 250; //右边区域最小宽度为150px
  836. // resize[i].style.left = moveLen; // 设置左侧区域的宽度
  837. for (let j = 0; j < left.length; j++) {
  838. left[j].style.width = moveLen + "px";
  839. mid[j].style.width = box[i].clientWidth - moveLen - 1 + "px";
  840. }
  841. };
  842. // 鼠标松开事件
  843. document.onmouseup = (evt) => {
  844. this.$refs.monaco.init(this.opts)
  845. //颜色恢复
  846. resize[i].style.background = "#d6d6d6";
  847. document.onmousemove = null;
  848. document.onmouseup = null;
  849. resize[i].releaseCapture && resize[i].releaseCapture(); //当你不在需要继续获得鼠标消息就要应该调用ReleaseCapture()释放掉
  850. };
  851. resize[i].setCapture && resize[i].setCapture(); //该函数在属于当前线程的指定窗口里设置鼠标捕获
  852. return false;
  853. };
  854. }
  855. },
  856. // 更改语言
  857. changeLanguage(val) {
  858. this.opts.language = val;
  859. },
  860. // 更换主题
  861. changeTheme(val) {
  862. this.opts.theme = val;
  863. },
  864. // 手动获取值
  865. getValue() {
  866. console.log(`输出代码:${this.$refs.monaco.getVal()}`);
  867. },
  868. // 保存按钮的回调事件
  869. handleSave(val) {
  870. // this.monacaValue = Buffer.from(val).toString("base64");
  871. const readvalue = async () => {
  872. const k = await readByMainKey({
  873. tableName: "git",
  874. key: encodeURI(this.fileInfoParams.filePath),
  875. });
  876. if (k.d) {
  877. if (!k.d.language)
  878. k.d.language = this.opts.language;
  879. k.d.fileType = this.fileInfo.fileType;
  880. if (val === k.d.oldContent) {
  881. remove({
  882. tableName: "git",
  883. key: encodeURI(this.fileInfoParams.filePath),
  884. });
  885. } else {
  886. k.d.newContent = val;
  887. add({
  888. tableName: "git",
  889. data: { name: encodeURI(this.fileInfoParams.filePath), d: k.d },
  890. });
  891. }
  892. } else {
  893. this.fileInfoParams.newContent = val;
  894. this.fileInfoParams.language = this.fileInfo.language;
  895. this.fileInfoParams.fileType = this.fileInfo.fileType;
  896. add({
  897. tableName: "git",
  898. data: {
  899. name: encodeURI(this.fileInfoParams.filePath),
  900. d: this.fileInfoParams,
  901. },
  902. });
  903. }
  904. this.treeNodeModify();
  905. };
  906. readvalue();
  907. // const base64Content = Buffer.from(val).toString("base64");
  908. // if (this.fileInfoParams.operation === "add") {
  909. // // 说明这条是新增的
  910. // this.treeRootData = RecurveUpdateValue(
  911. // this.treeRootData,
  912. // this.fileInfoParams,
  913. // base64Content
  914. // );
  915. // this.treeNodeModify(this.treeRootData);
  916. // }
  917. },
  918. async reload() {
  919. this.containerReload = false;
  920. await this.$nextTick();
  921. this.containerReload = true;
  922. },
  923. handleSetting() {
  924. this.drawerVisible = true;
  925. },
  926. handleChangeModelOptions(value) {
  927. this.opts.theme = value;
  928. this.$refs.monaco.setTheme(value)
  929. },
  930. handleChangeFontSizeOptions(value) {
  931. this.opts.fontSize = value;
  932. this.$refs.monaco.updateOptions(this.opts)
  933. },
  934. // 倒计时
  935. countDown() {
  936. let h = parseInt((this.headerParams.remainingTime / (60 * 60)) % 24);
  937. h = h < 10 ? `0${h}` : h;
  938. let m = parseInt((this.headerParams.remainingTime / 60) % 60);
  939. m = m < 10 ? `0${m}` : m;
  940. let s = parseInt(this.headerParams.remainingTime % 60);
  941. s = s < 10 ? `0${s}` : s;
  942. this.count = `${h}:${m}:${s}`;
  943. },
  944. // 定时器没过1秒参数减1
  945. Time() {
  946. this.timer = setInterval(() => {
  947. this.headerParams.remainingTime -= 1;
  948. if (this.headerParams.remainingTime === 0) clearInterval(this.timer);
  949. this.countDown();
  950. }, 1000);
  951. },
  952. },
  953. };
  954. </script>
  955. <style lang="less" scoped>
  956. .hides {
  957. // visibility: hidden;
  958. position: relative;
  959. z-index: -1;
  960. }
  961. .showImg{
  962. width: 100%;
  963. height: 100%;
  964. display: flex;
  965. justify-content: center;
  966. align-items: center;
  967. background: #f1f1f1;
  968. }
  969. .showOffice,.showPdf{
  970. width: 100%;
  971. height: 100%;
  972. }
  973. .showOffice iframe,.showPdf embed{
  974. width: 100%;
  975. height: 100%;
  976. border: none;
  977. background: white;
  978. }
  979. .showImg img{
  980. max-height: 100%;
  981. max-width:100%;
  982. }
  983. .ide-header {
  984. background: #363840;
  985. width: 100%;
  986. height: 60px;
  987. //border: 1px solid #363840;
  988. display: flex;
  989. padding-left: 32px;
  990. justify-content: space-between;
  991. align-items: center;
  992. span {
  993. display: flex;
  994. align-items: center;
  995. font-size: 14px;
  996. font-family: PingFangSC-Medium, PingFang SC;
  997. font-weight: 500;
  998. color: #ffffff;
  999. line-height: 60px;
  1000. .ide-header-svg{
  1001. margin-right: 8px;
  1002. width: 13px;
  1003. height: 19px;
  1004. }
  1005. }
  1006. }
  1007. .el-icon-switch-button {
  1008. line-height: 60px;
  1009. margin-right: 20px;
  1010. cursor: pointer;
  1011. color: #FFFFFF;
  1012. font-size: 14px;
  1013. }
  1014. .inlineBlock {
  1015. display: inline-block;
  1016. float: left;
  1017. }
  1018. .menu-left {
  1019. display: inline-block;
  1020. width: 75px;
  1021. background-color: #F5F5F5;
  1022. height: calc(100vh - 60px);
  1023. //.menu-left-drag-img {
  1024. // width: 24px;
  1025. // height: 24px;
  1026. //}
  1027. .menu-left-drag {
  1028. li {
  1029. height: 70px;
  1030. }
  1031. &-svg{
  1032. height: 24px;
  1033. width: 30px;
  1034. color: #7A7A7B;
  1035. margin-bottom: 8px;
  1036. }
  1037. }
  1038. .el-menu {
  1039. border-right: none;
  1040. .el-menu-item {
  1041. padding: 10px 20px;
  1042. height: none;
  1043. }
  1044. }
  1045. }
  1046. .activeBack {
  1047. background: #ffffff !important;
  1048. padding: 19px 21px 45px 22px !important;
  1049. border: 1px solid #D4D4D5;
  1050. .menu-left-drag-svg{
  1051. color: #000000;
  1052. }
  1053. }
  1054. .leftPaneBase {
  1055. //background: #e6f1f6;
  1056. //border: 1px solid #dededf;
  1057. height: calc(100vh - 40px);
  1058. &-submit {
  1059. background: #F5F5F6;
  1060. border: 1px solid #D4D4D5;
  1061. height: 52px;
  1062. padding: 0 36px;
  1063. font-size: 14px;
  1064. font-family: PingFangSC-Medium, PingFang SC;
  1065. font-weight: 500;
  1066. color: #000000;
  1067. line-height: 52px;
  1068. }
  1069. &-wrap {
  1070. &-change {
  1071. padding: 0 20px;
  1072. height: 54px;
  1073. line-height: 54px;
  1074. display: flex;
  1075. justify-content: space-between;
  1076. &-svg{
  1077. width: 16px;
  1078. height: 16px;
  1079. }
  1080. &-img {
  1081. cursor: pointer;
  1082. margin-top: 20px;
  1083. }
  1084. }
  1085. &-fileName {
  1086. height: calc(100vh - 508px);
  1087. overflow-y: auto;
  1088. &-item {
  1089. padding: 0 20px;
  1090. height: 34px;
  1091. font-size: 14px;
  1092. font-family: PingFangSC-Regular, PingFang SC;
  1093. font-weight: 400;
  1094. color: #000000;
  1095. line-height: 34px;
  1096. overflow: hidden;
  1097. text-overflow: ellipsis;
  1098. white-space: nowrap;
  1099. display: flex;
  1100. align-items: center;
  1101. justify-content: space-between;
  1102. span {
  1103. cursor: pointer;
  1104. }
  1105. &-img {
  1106. cursor: pointer;
  1107. opacity: 0;
  1108. }
  1109. }
  1110. &-item:hover {
  1111. background: #F6F9FC;
  1112. span {
  1113. color: #409EFF;
  1114. }
  1115. .leftPaneBase-wrap-fileName-item-img {
  1116. opacity: 1;
  1117. color: #2285d0;
  1118. }
  1119. }
  1120. }
  1121. &-info {
  1122. padding: 0 20px;
  1123. font-size: 14px;
  1124. font-family: PingFangSC-Regular, PingFang SC;
  1125. font-weight: 400;
  1126. color: #000000;
  1127. margin: 30px 0 10px;
  1128. }
  1129. &-input {
  1130. padding: 0 20px;
  1131. margin-bottom: 10px;
  1132. .el-textarea__inner {
  1133. background: #dae9f3;
  1134. max-height: 200p "max-content";
  1135. max-height: 200px;
  1136. }
  1137. }
  1138. &-infoSubmit {
  1139. width: 100%;
  1140. background: #363742;
  1141. border: 0px;
  1142. }
  1143. }
  1144. }
  1145. .resize {
  1146. //position: absolute;
  1147. //top: 145px;
  1148. //display: inline-block;
  1149. //width: 2px;
  1150. //height: calc(100% - 145px);
  1151. //border-radius: 5px;
  1152. //margin-top: -51px;
  1153. //cursor: pointer;
  1154. background: #dce3e8;
  1155. //background-position: center;
  1156. /* z-index: 99999; */
  1157. //font-size: 14px;
  1158. //color: white;
  1159. //margin-left: -1px;
  1160. //float: left;
  1161. //cursor: col-resize;
  1162. //z-index: 999;
  1163. position: absolute;
  1164. top: 160px;
  1165. display: inline-block;
  1166. width: 2px;
  1167. height: calc(100vh - 100px);
  1168. border-radius: 5px;
  1169. margin-top: -51px;
  1170. margin-left: -1px;
  1171. cursor: col-resize;
  1172. z-index: 999;
  1173. }
  1174. .mid {
  1175. float: left;
  1176. width: calc(100% - 300px);
  1177. /*右侧初始化宽度*/
  1178. height: calc(100vh - 42px);
  1179. background: #fff;
  1180. position: relative;
  1181. }
  1182. .box {
  1183. width: 100%;
  1184. overflow: hidden;
  1185. }
  1186. .empty-tip {
  1187. text-align: center;
  1188. width: 100%;
  1189. height: 100%;
  1190. display: flex;
  1191. align-items: center;
  1192. justify-content: center;
  1193. flex-direction: column;
  1194. color: #999;
  1195. }
  1196. .mid-header {
  1197. height: 54px;
  1198. background: #f0f0f0;
  1199. border: 1px solid #dadadb;
  1200. line-height: 54px;
  1201. display: flex;
  1202. width: 100%;
  1203. justify-content: space-between;
  1204. padding: 0 20px;
  1205. font-size: 14px;
  1206. font-family: PingFangSC-Regular, PingFang SC;
  1207. font-weight: 400;
  1208. color: #000000;
  1209. span:nth-child(2) {
  1210. .el-icon-s-tools {
  1211. margin-left: 5px;
  1212. cursor: pointer;
  1213. }
  1214. }
  1215. }
  1216. .drawer-wrap {
  1217. font-size: 14px;
  1218. font-family: PingFangSC-Regular, PingFang SC;
  1219. .el-drawer {
  1220. background-color: #e6f1f6 !important;
  1221. }
  1222. .drawer-wrap-span{
  1223. height: 20px;
  1224. font-weight: 400;
  1225. color: #7A7A7B;
  1226. line-height: 20px;
  1227. }
  1228. .drawer-wrap-span2{
  1229. height: 20px;
  1230. font-weight: 400;
  1231. color: #000000;
  1232. line-height: 20px;
  1233. }
  1234. }
  1235. .code-fast {
  1236. font-weight: 500;
  1237. margin-bottom: 30px;
  1238. height: 20px;
  1239. font-size: 14px;
  1240. font-family: PingFangSC-Medium, PingFang SC;
  1241. font-weight: 500;
  1242. color: #000000;
  1243. line-height: 20px;
  1244. }
  1245. .drawer-section {
  1246. height: 100%;
  1247. //background: #e6f1f6;
  1248. background: #f0f0f0;
  1249. padding: 25px 26px 0;
  1250. .el-select {
  1251. width: 140px;
  1252. font-weight: 400;
  1253. color: #000000;
  1254. }
  1255. &-stydrawer-sectionle-wrap{
  1256. display: flex;
  1257. align-items: center;
  1258. justify-content: space-between;
  1259. margin-bottom: 20px;
  1260. }
  1261. &-style {
  1262. border-bottom: 1px solid #b1bacd;
  1263. padding-bottom: 30px;
  1264. margin-bottom: 30px;
  1265. &-wrap {
  1266. display: flex;
  1267. justify-content: space-between;
  1268. align-items: center;
  1269. margin-bottom: 20px;
  1270. }
  1271. }
  1272. .drawer-fast {
  1273. &-flex {
  1274. display: flex;
  1275. justify-content: space-between;
  1276. margin-bottom: 20px;
  1277. font-weight: 400;
  1278. color: #333333;
  1279. line-height: 14px;
  1280. }
  1281. }
  1282. }
  1283. .vscode-header {
  1284. display: flex;
  1285. justify-content: space-between;
  1286. line-height: 40px;
  1287. font-size: 14px;
  1288. font-family: PingFangSC-Medium, PingFang SC;
  1289. font-weight: 500;
  1290. color: #ffffff;
  1291. height: 40px;
  1292. padding: 0 20px;
  1293. background: #051019;
  1294. }
  1295. .color {
  1296. color: #f8cd47;
  1297. }
  1298. .mr5 {
  1299. margin-right: 5px;
  1300. }
  1301. .mr40 {
  1302. margin-right: 40px;
  1303. }
  1304. .cspointe {
  1305. cursor: pointer;
  1306. }
  1307. .iframe-wrap {
  1308. width: 100%;
  1309. height: calc(100vh - 40px);
  1310. border: none;
  1311. }
  1312. .vscode-loading-wrap {
  1313. width: 100%;
  1314. height: 100vh;
  1315. }
  1316. .no-commit {
  1317. color: #999;
  1318. text-align: center;
  1319. padding-top: 20px;
  1320. }
  1321. </style>
  1322. <style scoped>
  1323. /deep/.el-drawer{
  1324. box-shadow: none;
  1325. }
  1326. :focus{
  1327. outline: none;
  1328. }
  1329. .icon {
  1330. width: 1em;
  1331. height: 1em;
  1332. vertical-align: -0.15em;
  1333. fill: currentColor;
  1334. overflow: hidden;
  1335. }
  1336. #nbview{
  1337. position: absolute;
  1338. width: 100%;
  1339. height: calc(100% - 54px);
  1340. left:0;
  1341. top:54px;
  1342. z-index: 1;
  1343. background: #FFF;
  1344. border:none;
  1345. }
  1346. </style>