CodePane.vue 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. <template>
  2. <v-card class="d-flex flex-column questionCard pa-0">
  3. <div class="my-1 d-flex flex-grow-1 pa-1">
  4. <div class="flex-grow-1 d-flex flex-column justify-space-between">
  5. <div>
  6. <v-tabs v-model="tab" class="pa-0 ma-0 elevation-1" grow>
  7. <v-tab>题目描述</v-tab>
  8. <v-tab>提交记录</v-tab>
  9. </v-tabs>
  10. <v-tabs-items v-model="tab">
  11. <v-tab-item>
  12. <div class="overflow-y-auto" style="height: 80vh">
  13. <markdown-text :raw="stem" style="height: 100%"></markdown-text>
  14. </div>
  15. </v-tab-item>
  16. <v-tab-item class="pa-2">
  17. <div class="d-flex flex-column justify-space-between pa-2">
  18. <v-card
  19. flat
  20. class="d-flex flex-column justify-space-between mb-5"
  21. >
  22. <div class="d-inline mb-2">
  23. 执行结果:
  24. <v-chip
  25. :color="statusToColor(currentCommit.status)"
  26. outlined
  27. >{{ currentCommit.status }}</v-chip
  28. >
  29. </div>
  30. <v-card-text
  31. style="background-color: darkgray; height: 30vh"
  32. class="rounded ma-0 mb-5 overflow-y-auto pa-2"
  33. v-if="
  34. currentCommit && currentCommit.status === '编译或运行失败'
  35. "
  36. >
  37. TODO
  38. </v-card-text>
  39. </v-card>
  40. <!-- <v-simple-table fixed-header height="40vh" class="flex-grow-1">-->
  41. <v-simple-table
  42. fixed-header
  43. :height="
  44. currentCommit && currentCommit.status === '编译或运行失败'
  45. ? 35 + 'vh'
  46. : 70 + 'vh'
  47. "
  48. >
  49. <thead>
  50. <tr>
  51. <th>提交时间</th>
  52. <th>状态</th>
  53. <th>成绩</th>
  54. <th>操作</th>
  55. </tr>
  56. </thead>
  57. <tbody>
  58. <tr v-for="item in commits" :key="item.id">
  59. <td>{{ item.submitTime }}</td>
  60. <td>
  61. <v-chip
  62. :color="statusToColor(item.status)"
  63. small
  64. outlined
  65. >
  66. {{ item.status }}
  67. </v-chip>
  68. </td>
  69. <td>{{ item.score }}</td>
  70. <td>
  71. <v-btn small>详情</v-btn>
  72. </td>
  73. </tr>
  74. </tbody>
  75. </v-simple-table>
  76. </div>
  77. </v-tab-item>
  78. </v-tabs-items>
  79. </div>
  80. <div style="height: 32px" class="d-flex justify-space-between">
  81. <v-btn color="info" small>上一题</v-btn>
  82. <span> 代码题 1/4</span>
  83. <v-btn color="info" small>下一题</v-btn>
  84. </div>
  85. </div>
  86. <v-divider vertical class="mx-1"></v-divider>
  87. <div style="width: 50vw; height: 100%" class="d-flex flex-column">
  88. <div
  89. style="height: 48px"
  90. class="d-flex pr-5 justify-space-between elevation-1 mb-1"
  91. >
  92. <div class="d-flex ml-5">
  93. <div class="d-flex">
  94. <v-select
  95. :items="languages"
  96. v-model="currentLang"
  97. dense
  98. style="width: 120px"
  99. class=" ma-0 pa-0"
  100. solo
  101. >
  102. </v-select>
  103. </div>
  104. <v-tooltip top>
  105. <template v-slot:activator="{ on, attrs }">
  106. <v-btn
  107. fab
  108. x-small
  109. tile
  110. class="mx-2 mb-2 pa-0 elevation-1 align-self-center"
  111. v-bind="attrs"
  112. v-on="on"
  113. >
  114. <v-icon>mdi-arrow-left</v-icon>
  115. </v-btn>
  116. </template>
  117. <span>恢复到上次提交的代码</span>
  118. </v-tooltip>
  119. <v-tooltip top>
  120. <template v-slot:activator="{ on, attrs }">
  121. <v-btn
  122. fab
  123. x-small
  124. tile
  125. class="mx-2 mb-2 pa-0 elevation-1 align-self-center"
  126. v-bind="attrs"
  127. v-on="on"
  128. >
  129. <v-icon>mdi-refresh</v-icon>
  130. </v-btn>
  131. </template>
  132. <span>重置代码至初始状态</span>
  133. </v-tooltip>
  134. </div>
  135. <v-btn
  136. color="primary"
  137. class="mx-2 mb-2 align-self-center"
  138. small
  139. v-on:click="submitCode"
  140. >保存测试</v-btn
  141. >
  142. </div>
  143. <code-editor
  144. :language="currentLang"
  145. v-model="currentCode"
  146. ></code-editor>
  147. </div>
  148. </div>
  149. </v-card>
  150. </template>
  151. <script lang="ts">
  152. import Vue from 'vue'
  153. import CodeEditor from '@/views/exam/components/CodeEditor.vue'
  154. import MarkdownText from '@/views/exam/components/MarkdownText.vue'
  155. import { clone } from 'ramda'
  156. interface CommitInfo {
  157. id?: string
  158. submitTime?: string
  159. status?: string
  160. score?: number
  161. codes?: CodeQuestionPair[]
  162. msg?: string
  163. }
  164. interface CodeQuestionPair {
  165. id?: string
  166. stem?: string
  167. originalCode?: LanguageCode[]
  168. currentCode?: LanguageCode[]
  169. }
  170. interface LanguageCode {
  171. type?: string
  172. code?: string
  173. }
  174. export default Vue.extend({
  175. components: {
  176. CodeEditor,
  177. MarkdownText
  178. },
  179. data() {
  180. return {
  181. content: '213123123',
  182. tab: null,
  183. commits: [] as CommitInfo[],
  184. languages: ['cpp', 'java', 'python'],
  185. currentLang: 'java',
  186. currentCommit: (null as unknown) as CommitInfo,
  187. statusTags: [
  188. '所有用例通过',
  189. '有用例未通过',
  190. '编译或运行失败',
  191. '运行超时',
  192. '等待运行'
  193. ],
  194. statusColors: ['success', 'warning', 'error', 'accent', 'info'],
  195. stem: '',
  196. codeQuestions: [] as CodeQuestionPair[],
  197. currentQuestion: {} as CodeQuestionPair,
  198. currentCode: [] as CodeQuestionPair[]
  199. }
  200. },
  201. computed: {
  202. // lastEdit: function() {
  203. // return clone(this.currentQuestion.currentCode)
  204. // },
  205. //
  206. // codeByLanguage() {
  207. // for (const languageCode of this.currentQuestion.currentCode) {
  208. // if (this.currentLang === languageCode.type) {
  209. // return languageCode.code
  210. // }
  211. // }
  212. // return ''
  213. // }
  214. },
  215. watch: {
  216. // currentLang() {
  217. // this.currentCode = this.codeByLanguage
  218. // }
  219. },
  220. beforeMount() {
  221. for (let i = 0; i < 10; i++) {
  222. const r = Math.floor(Math.random() * 4 + 1)
  223. this.commits.push({
  224. id: i.toString(),
  225. submitTime: '2020-12-11 20:02',
  226. status: this.statusTags[r],
  227. score: 6 * i
  228. })
  229. }
  230. this.currentCommit = this.getCurrentCommit()
  231. this.fetchData()
  232. },
  233. methods: {
  234. submitCode(): void {
  235. const r = Math.floor(Math.random() * 5)
  236. const id = Math.floor(Math.random() * 1000).toString()
  237. this.commits = [
  238. {
  239. id: id,
  240. submitTime: '2020-12-11 20:03',
  241. status: this.statusTags[r],
  242. score: 100
  243. },
  244. ...this.commits
  245. ]
  246. this.currentCommit = this.getCurrentCommit()
  247. console.log(this.currentCode)
  248. },
  249. getCurrentCommit(): CommitInfo {
  250. return this.commits[0]
  251. },
  252. statusToColor(status: string): string {
  253. return this.statusColors[this.statusTags.indexOf(status)]
  254. },
  255. fetchData() {
  256. const cpp = { type: 'cpp', code: 'int main(){}' } as LanguageCode
  257. const java = { type: 'java', code: 'int a=0;' } as LanguageCode
  258. const python = { type: 'python', code: 'print a' } as LanguageCode
  259. this.currentQuestion = {
  260. id: '123',
  261. stem: 'description',
  262. originalCode: [cpp, java, python],
  263. currentCode: [cpp, java, python]
  264. }
  265. this.codeQuestions.push(this.currentQuestion)
  266. this.codeQuestions.push({
  267. id: '234',
  268. stem: 'description',
  269. originalCode: [cpp, java, python],
  270. currentCode: [cpp, java, python]
  271. })
  272. // this.currentCode = this.codeByLanguage
  273. console.log(this.currentCode)
  274. },
  275. resetCode() {
  276. for (const codeQuestion of this.codeQuestions) {
  277. if (codeQuestion.id === this.currentQuestion.id) {
  278. this.currentQuestion.currentCode = clone(codeQuestion.originalCode)
  279. }
  280. // 添加完成后的提示
  281. }
  282. }
  283. }
  284. })
  285. </script>
  286. <style scoped>
  287. .questionCard {
  288. margin: 0.5vh;
  289. height: 92vh;
  290. }
  291. </style>