CommitDetails.vue 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. <template>
  2. <div>
  3. <!-- <el-row-->
  4. <!-- style="display: flex;flex-direction: row;align-items: center;margin-bottom: 10px;color: #333333">-->
  5. <!-- <el-button plain icon="el-icon-arrow-left" @click="goBack">上一页</el-button>-->
  6. <!-- </el-row>-->
  7. <el-card shadow="never" class="description-card">
  8. <!-- <el-button plain icon="el-icon-arrow-left" @click="goBack" style="margin-right: 20px">返回</el-button>-->
  9. <el-link
  10. target="_blank"
  11. class="commit-id description-card-text"
  12. @click.stop.prevent="copy(commitId.id)"
  13. >
  14. <span>{{ commitId }}</span>
  15. <i class="el-icon-document-copy"></i>
  16. </el-link>
  17. <!-- <div class="description-card-text commit-title">标题:-->
  18. <!-- <span>{{ commitInfo.title }}</span>-->
  19. <!-- </div>-->
  20. <div class="description-card-text">信息:
  21. <span>{{ commitInfo.message }}</span>
  22. </div>
  23. <div class="description-card-text">时间:
  24. <span>{{ commitInfo.timestamp }}</span>
  25. </div>
  26. <div class="description-card-text">提交人:
  27. <span>{{ commitInfo.gitlabUsername }}</span>
  28. </div>
  29. <div class="description-card-text">
  30. <el-row>
  31. parents:
  32. <span><el-tag v-for="(parent, index) in commitInfo.parents"
  33. :key="index"
  34. @click="onParentTagClick(parent)"
  35. >{{ parent }}</el-tag></span>
  36. </el-row>
  37. </div>
  38. </el-card>
  39. <el-divider content-position="left">
  40. 变更详情
  41. </el-divider>
  42. <div v-if="parentsCount > 0">
  43. <el-row :gutter="20">
  44. <el-col :span="8">
  45. <el-row :gutter="20">
  46. <el-col :span="12">
  47. <div class="grid-content">
  48. <el-select v-model="currentParentIndex" style="width: 100%">
  49. <el-option
  50. v-for="(item, index) in commitInfo.parents"
  51. :key="index"
  52. :label="'相比于 parent ' + item.substring(0,8)"
  53. :value="index">
  54. </el-option>
  55. </el-select>
  56. </div>
  57. </el-col>
  58. <el-col :span="12">
  59. <el-input
  60. v-model="fileNameKeyword"
  61. class="w-50 m-2"
  62. placeholder="检索文件名"
  63. :prefix-icon="Search"
  64. >
  65. <template #append>
  66. <el-button :icon="Search" @click="searchFileName">搜索</el-button>
  67. </template>
  68. </el-input>
  69. </el-col>
  70. </el-row>
  71. <el-row>
  72. <el-table :data="displayDiff[currentParentIndex]"
  73. max-height="350px"
  74. style="width: 100%"
  75. highlight-current-row
  76. @current-change="handleCurrentChange">
  77. <el-table-column prop="newPath" label="文件"/>
  78. <el-table-column prop="state" label="状态" width="100">
  79. <template #default="scope">
  80. <el-tag
  81. :type="scope.row.state < 0 ? 'danger' : (scope.row.state === 0 ? 'success' : '')"
  82. disable-transitions>
  83. {{ scope.row.stateDes }}
  84. </el-tag>
  85. </template>
  86. </el-table-column>
  87. </el-table>
  88. </el-row>
  89. </el-col>
  90. <el-col :span="16" style="height: 400px">
  91. <el-empty v-if="diffHtml === ''" description="请在左侧选择文件查看" />
  92. <div v-html="diffHtml" v-cloak ></div>
  93. </el-col>
  94. </el-row>
  95. </div>
  96. <div v-else>
  97. <el-empty description="本次提交为首次提交,无法比较" />
  98. </div>
  99. </div>
  100. <!-- {{commitInfo}}-->
  101. </template>
  102. <script>
  103. import { ProjectAPI } from '@/api';
  104. import * as Diff2Html from 'diff2html';
  105. import 'diff2html/bundles/css/diff2html.min.css';
  106. import { copy } from '@/utils/clipboard';
  107. import { ref } from 'vue';
  108. import { formatter } from '../../utils/time';
  109. export default {
  110. name: 'CommitDetials.vue',
  111. data() {
  112. return {
  113. commitInfo: {},
  114. originAllDiffs: [],
  115. diffString: '',
  116. parentsCount: 0,
  117. currentParentIndex: 0,
  118. diffHtml: '',
  119. fileNameKeyword: '',
  120. displayDiff: [],
  121. currentFileRow: ref(),
  122. };
  123. },
  124. computed: {
  125. projectId() {
  126. return this.$route.params.projectId;
  127. },
  128. commitId() {
  129. return this.$route.query.id;
  130. },
  131. },
  132. async mounted() {
  133. await this.loadCommitInfo();
  134. },
  135. methods: {
  136. copy,
  137. async loadCommitInfo() {
  138. this.commitInfo = await ProjectAPI.getCommitByHash(this.$store.state.workspace.currentProjectId, this.commitId);
  139. this.commitInfo.timestamp = formatter(this.commitInfo.timestamp);
  140. this.parentsCount = this.commitInfo.parents.length;
  141. for (let i = 0; i < this.parentsCount; i += 1) {
  142. const parentHash = this.commitInfo.parents[i];
  143. // eslint-disable-next-line no-await-in-loop
  144. const diffFiles = await ProjectAPI.getCommitsDiff(this.$store.state.workspace.currentProjectId, parentHash, this.commitId);
  145. for (let j = 0; j < diffFiles.length; j += 1) {
  146. const diffFile = diffFiles[j];
  147. if (diffFile.deletedFile) {
  148. diffFile.state = -1;
  149. diffFile.stateDes = '删除';
  150. } else if (diffFile.newFile) {
  151. diffFile.state = 0;
  152. diffFile.stateDes = '新增';
  153. } else if (diffFile.renamedFile) {
  154. diffFile.state = 1;
  155. diffFile.stateDes = '改名';
  156. } else {
  157. diffFile.state = 2;
  158. diffFile.stateDes = '修改';
  159. }
  160. }
  161. this.originAllDiffs.push(diffFiles);
  162. }
  163. this.displayDiff = this.originAllDiffs;
  164. },
  165. drawDiffHtml() {
  166. // this.diffString = this.diff[this.currentParentIndex][0].diff;
  167. this.diffString = this.currentFileRow.diff;
  168. this.diffHtml = Diff2Html.html(this.diffString, {
  169. drawFileList: false,
  170. matching: 'lines',
  171. outputFormat: 'line-by-line',
  172. // maxLineSizeInBlockForComparison: 10,
  173. });
  174. },
  175. goBack() {
  176. this.$router.go(-1);
  177. this.loadCommitInfo();
  178. },
  179. handleCurrentChange(val) {
  180. this.currentFileRow = val;
  181. this.drawDiffHtml();
  182. },
  183. onParentTagClick(id) {
  184. console.log(id);
  185. // this.$router.push({
  186. // path: `/project/${this.$store.state.workspace.currentProjectId}/commit-detail`,
  187. // query: {
  188. // id,
  189. // },
  190. // });
  191. // this.loadCommitInfo();
  192. },
  193. searchFileName() {
  194. this.displayDiff = [];
  195. for (let i = 0; i < this.parentsCount; i += 1) {
  196. this.displayDiff.push(this.originAllDiffs[i]
  197. .filter((diffFile) => diffFile.newPath.indexOf(this.fileNameKeyword) >= 0));
  198. }
  199. },
  200. },
  201. };
  202. </script>
  203. <style scoped>
  204. .el-row {
  205. margin-bottom: 20px;
  206. }
  207. [v-cloak] {
  208. display: none;
  209. }
  210. .description-card {
  211. margin: 10px 0;
  212. }
  213. .description-card-text {
  214. margin: 5px 0;
  215. }
  216. .commit-id {
  217. font-size: 18px;
  218. font-weight: bold;
  219. }
  220. .commit-title {
  221. font-weight: bold;
  222. }
  223. .el-tag {
  224. margin: 3px 10px;
  225. }
  226. </style>