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.

Images.vue 26 kB

3 years ago
4 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
3 years ago
3 years ago
3 years ago
4 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
3 years ago
3 years ago
3 years ago
4 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
3 years ago
3 years ago
4 years ago
4 years ago
3 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638
  1. <template>
  2. <div>
  3. <div class="header-wrapper">
  4. <div class="ui container">
  5. <el-row class="image_text">
  6. <h1>云脑镜像</h1>
  7. </el-row>
  8. </div>
  9. </div>
  10. <div class="ui container" id="header">
  11. <el-tabs v-model="activeName" @tab-click="handleClick">
  12. <el-tab-pane label="公开镜像" name="first" v-loading="loadingPublic">
  13. <template v-if="tableDataPublic.length!==0">
  14. <div class="ui sixteen wide column">
  15. <div class="ui two column stackable grid">
  16. <div class="column">
  17. <el-input placeholder="请输入镜像名称关健词" v-model="search" class="input-with-select" @keyup.enter.native="searchName()">
  18. <el-button id="success" slot="append" icon="el-icon-search" @click="searchName()">搜索</el-button>
  19. </el-input>
  20. </div>
  21. </div>
  22. </div>
  23. <el-row style="margin-top:15px;">
  24. <el-table
  25. :data="tableDataPublic"
  26. style="width: 100%"
  27. :header-cell-style="tableHeaderStyle"
  28. >
  29. <el-table-column
  30. label="镜像名称"
  31. min-width="19%"
  32. align="left"
  33. prop="tag"
  34. >
  35. <template slot-scope="scope">
  36. <div style="display: flex;align-items: center;">
  37. <a class="text-over image_title" :title="scope.row.tag">{{ scope.row.tag }}</a>
  38. <i class="ri-lock-2-line" style="color: #fa8c16;" v-if="scope.row.isPrivate"></i>
  39. </div>
  40. </template>
  41. </el-table-column>
  42. <el-table-column
  43. label="镜像描述"
  44. min-width="28%"
  45. align="left"
  46. prop="description"
  47. >
  48. <template slot-scope="scope">
  49. <div class="image_desc" :title="scope.row.description">{{ scope.row.description}}</div>
  50. <div v-if="!!scope.row.topics">
  51. <span v-for="(topic,index) in scope.row.topics" class="ui repo-topic label topic">{{topic}}</span>
  52. </div>
  53. </template>
  54. </el-table-column>
  55. <el-table-column
  56. prop="type"
  57. label="可用集群"
  58. min-width="10%"
  59. align="center"
  60. >
  61. <template slot-scope="scope">
  62. {{scope.row.type | transformType}}
  63. </template>
  64. </el-table-column>
  65. <el-table-column
  66. prop="creator"
  67. label="创建者"
  68. min-width="8%"
  69. align="center"
  70. >
  71. <template slot-scope="scope">
  72. {{scope.row.isPrivate | transformPravite}}
  73. </template>
  74. </el-table-column>
  75. <el-table-column
  76. prop="createdUnix"
  77. label="创建时间"
  78. align="center"
  79. min-width="14%"
  80. >
  81. <template slot-scope="scope">
  82. {{scope.row.createdUnix | transformTimestamp}}
  83. </template>
  84. </el-table-column>
  85. <el-table-column
  86. align="center"
  87. min-width="21%"
  88. label="操作"
  89. >
  90. <template slot-scope="scope">
  91. <div style="display: flex;justify-content: flex-end;align-items: center;">
  92. <div style="display: flex;align-items: center;cursor:pointer;padding: 0 1rem;" @click="imageStar(scope.row.id)">
  93. <svg width="1.4em" height="1.4em" viewBox="0 0 32 32" class="heart-stroke"><path d="M4.4 6.54c-1.761 1.643-2.6 3.793-2.36 6.056.24 2.263 1.507 4.521 3.663 6.534a29110.9 29110.9 0 0010.296 9.633l10.297-9.633c2.157-2.013 3.424-4.273 3.664-6.536.24-2.264-.599-4.412-2.36-6.056-1.73-1.613-3.84-2.29-6.097-1.955-1.689.25-3.454 1.078-5.105 2.394l-.4.319-.398-.319c-1.649-1.316-3.414-2.143-5.105-2.394a7.612 7.612 0 00-1.113-.081c-1.838 0-3.541.694-4.983 2.038z"></path></svg>
  94. <span style="line-height: 2;margin-left:0.3rem;">3</span>
  95. </div>
  96. <span style="padding: 0 1rem;color:#0366d6;cursor:pointer;" @click="copyUrl(scope.row.place)">复制地址</span>
  97. </div>
  98. </template>
  99. </el-table-column>
  100. </el-table>
  101. </el-row>
  102. <div class="ui container" style="margin-top:50px;text-align:center">
  103. <el-pagination
  104. background
  105. @size-change="handleSizeChangePublic"
  106. @current-change="handleCurrentChangePublic"
  107. :current-page="currentPagePublic"
  108. :page-size="pageSizePublic"
  109. :page-sizes="[10,15,20]"
  110. layout="total, sizes, prev, pager, next, jumper"
  111. :total="totalNumPublic">
  112. </el-pagination>
  113. </div>
  114. </template>
  115. <el-empty v-else :image-size="200"></el-empty>
  116. </el-tab-pane>
  117. <el-tab-pane label="我的镜像" name="second" v-loading="loadingCustom">
  118. <template v-if="tableDataCustom.length!==0">
  119. <div class="ui sixteen wide column">
  120. <div class="ui two column stackable grid">
  121. <div class="column">
  122. <el-input placeholder="请输入镜像名称关健词" v-model="search" class="input-with-select" @keyup.enter.native="searchName()">
  123. <el-button slot="append" id="success" icon="el-icon-search" @click="searchName()">搜索</el-button>
  124. </el-input>
  125. </div>
  126. </div>
  127. </div>
  128. <el-row style="margin-top:15px;">
  129. <el-table
  130. :data="tableDataCustom"
  131. style="width: 100%"
  132. :header-cell-style="tableHeaderStyle"
  133. >
  134. <el-table-column
  135. label="镜像名称"
  136. min-width="19%"
  137. align="left"
  138. prop="tag"
  139. >
  140. <template slot-scope="scope">
  141. <div style="display: flex;align-items: center;">
  142. <a class="text-over image_title" :title="scope.row.tag">{{ scope.row.tag }}</a>
  143. <i class="ri-lock-2-line" style="color: #fa8c16;" v-if="scope.row.isPrivate"></i>
  144. </div>
  145. </template>
  146. </el-table-column>
  147. <el-table-column
  148. label="镜像描述"
  149. min-width="28%"
  150. align="left"
  151. prop="description"
  152. >
  153. <template slot-scope="scope">
  154. <div class="image_desc" :title="scope.row.description">{{ scope.row.description}}</div>
  155. <div v-if="!!scope.row.topics">
  156. <span v-for="(topic,index) in scope.row.topics" class="ui repo-topic label topic">{{topic}}</span>
  157. </div>
  158. </template>
  159. </el-table-column>
  160. <el-table-column
  161. prop="type"
  162. label="可用集群"
  163. min-width="10%"
  164. align="center"
  165. >
  166. <template slot-scope="scope">
  167. {{scope.row.type | transformType}}
  168. </template>
  169. </el-table-column>
  170. <el-table-column
  171. prop="isPrivate"
  172. label="状态"
  173. min-width="8%"
  174. align="center"
  175. >
  176. <template slot-scope="scope">
  177. {{scope.row.isPrivate | transformPravite}}
  178. </template>
  179. </el-table-column>
  180. <el-table-column
  181. prop="createdUnix"
  182. label="创建时间"
  183. align="center"
  184. min-width="14%"
  185. >
  186. <template slot-scope="scope">
  187. {{scope.row.createdUnix | transformTimestamp}}
  188. </template>
  189. </el-table-column>
  190. <el-table-column
  191. align="center"
  192. min-width="21%"
  193. label="操作"
  194. >
  195. <template slot-scope="scope">
  196. <div style="display: flex;justify-content: flex-end;align-items: center;">
  197. <div style="display: flex;align-items: center;cursor:pointer;padding: 0 1rem;" @click="imageStar(scope.row.id)">
  198. <svg width="1.4em" height="1.4em" viewBox="0 0 32 32" class="heart-stroke"><path d="M4.4 6.54c-1.761 1.643-2.6 3.793-2.36 6.056.24 2.263 1.507 4.521 3.663 6.534a29110.9 29110.9 0 0010.296 9.633l10.297-9.633c2.157-2.013 3.424-4.273 3.664-6.536.24-2.264-.599-4.412-2.36-6.056-1.73-1.613-3.84-2.29-6.097-1.955-1.689.25-3.454 1.078-5.105 2.394l-.4.319-.398-.319c-1.649-1.316-3.414-2.143-5.105-2.394a7.612 7.612 0 00-1.113-.081c-1.838 0-3.541.694-4.983 2.038z"></path></svg>
  199. <span style="line-height: 2;margin-left:0.3rem;">3</span>
  200. </div>
  201. <span style="padding: 0 1rem;color:#0366d6;cursor:pointer;" @click="copyUrl(scope.row.place)">复制地址</span>
  202. <div style="padding-left:1rem;cursor:pointer;">
  203. <el-dropdown size="medium">
  204. <span class="el-dropdown-link">
  205. 更多<i class="el-icon-arrow-down el-icon--right"></i>
  206. </span>
  207. <el-dropdown-menu slot="dropdown">
  208. <el-dropdown-item @click.native="eidtImage(scope.row.id)">编辑</el-dropdown-item>
  209. <el-dropdown-item style="color: red;" @click.native="deleteImage(scope.row.id)">删除</el-dropdown-item>
  210. </el-dropdown-menu>
  211. </el-dropdown>
  212. </div>
  213. </div>
  214. </template>
  215. </el-table-column>
  216. </el-table>
  217. </el-row>
  218. <div class="ui container" style="margin-top:50px;text-align:center">
  219. <el-pagination
  220. background
  221. @size-change="handleSizeChangeCustom"
  222. @current-change="handleCurrentChangeCustom"
  223. :current-page="currentPageCustom"
  224. :page-size="pageSizeCustom"
  225. :page-sizes="[5,15,20]"
  226. layout="total, sizes, prev, pager, next, jumper"
  227. :total="totalNumCustom">
  228. </el-pagination>
  229. </div>
  230. </template>
  231. <el-empty v-else :image-size="200"></el-empty>
  232. </el-tab-pane>
  233. <el-tab-pane label="我收藏的镜像" name="third">
  234. <template v-if="tableDataStar.length!==0">
  235. <div class="ui sixteen wide column">
  236. <div class="ui two column stackable grid">
  237. <div class="column">
  238. <el-input placeholder="请输入镜像名称关健词" v-model="search" class="input-with-select">
  239. <el-button slot="append" id="success" icon="el-icon-search">搜索</el-button>
  240. </el-input>
  241. </div>
  242. </div>
  243. </div>
  244. <el-row style="margin-top:15px;">
  245. <el-table
  246. :data="tableDataStar"
  247. style="width: 100%"
  248. :header-cell-style="tableHeaderStyle"
  249. :default-sort="{prop:'createtime',order:'descending'}">
  250. <el-table-column
  251. label="镜像名称"
  252. width="350"
  253. align="left"
  254. prop="name"
  255. sortable
  256. >
  257. <template slot-scope="scope">
  258. <a class="text-over" :title="scope.row.name" style="cursor:default;color:#426290">{{ scope.row.name }}</a>
  259. </template>
  260. </el-table-column>
  261. <el-table-column
  262. label="文件路径/镜像描述"
  263. width="450"
  264. align="left"
  265. >
  266. <template slot-scope="scope">
  267. <el-tooltip class="item" effect="dark" content="点击复制文件路径" placement="top">
  268. <a class="text-over" style="display:block;" @click="copyUrl(scope.row.place)">{{ scope.row.place }}</a>
  269. </el-tooltip>
  270. <span class="text-over" :title="scope.row.description | clearP">{{ scope.row.description | clearP }}</span>
  271. </template>
  272. </el-table-column>
  273. <el-table-column
  274. prop="provider"
  275. label="提供者"
  276. width="120"
  277. align="left"
  278. sortable>
  279. </el-table-column>
  280. <el-table-column
  281. prop="createtime"
  282. label="创建时间"
  283. align="center"
  284. sortable>
  285. <template slot-scope="scope">
  286. {{scope.row.createtime | transformTimestamp}}
  287. </template>
  288. </el-table-column>
  289. </el-table>
  290. </el-row>
  291. <div class="ui container" style="margin-top:50px;text-align:center">
  292. <el-pagination
  293. background
  294. @size-change="handleSizeChangeStar"
  295. @current-change="handleCurrentChangeStar"
  296. :current-page="currentPageStar"
  297. :page-size="pageSizeStar"
  298. :page-sizes="[5,15,20]"
  299. layout="total, sizes, prev, pager, next, jumper"
  300. :total="totalNumStar">
  301. </el-pagination>
  302. </div>
  303. </template>
  304. <el-empty v-else :image-size="200"></el-empty>
  305. </el-tab-pane>
  306. </el-tabs>
  307. </div>
  308. </div>
  309. </template>
  310. <script>
  311. const {_AppSubUrl, _StaticUrlPrefix, csrf} = window.config;
  312. export default {
  313. components: {
  314. },
  315. data() {
  316. return {
  317. activeName: 'first',
  318. search:'',
  319. currentPagePublic:1,
  320. pageSizePublic:15,
  321. totalNumPublic:0,
  322. paramsPublic:{page:1,pageSize:15,q:'',recommend:false},
  323. tableDataPublic: [],
  324. loadingPublic:false,
  325. currentPageCustom:1,
  326. pageSizeCustom:15,
  327. totalNumCustom:0,
  328. paramsCustom:{page:1,pageSize:15,q:''},
  329. tableDataCustom: [],
  330. loadingCustom:false,
  331. currentPageStar:1,
  332. pageSizeStar:15,
  333. totalNumStar:0,
  334. paramsStar:{page:1,pageSize:15,q:''},
  335. tableDataStar: [],
  336. loadingStar:false
  337. };
  338. },
  339. methods: {
  340. handleClick(tab, event) {
  341. if(tab.name=="first"){
  342. this.getImageListPublic()
  343. }
  344. if(tab.name=="second"){
  345. this.getImageListCustom()
  346. }
  347. if(tab.name=="third"){
  348. this.getImageListStar()
  349. }
  350. },
  351. tableHeaderStyle({row,column,rowIndex,columnIndex}){
  352. if(rowIndex===0){
  353. return 'background:#f5f5f6;color:#606266'
  354. }
  355. },
  356. handleSizeChangePublic(val){
  357. this.paramsPublic.pageSize = val
  358. this.getImageListPublic()
  359. },
  360. handleCurrentChangePublic(val){
  361. this.paramsPublic.page = val
  362. this.getImageListPublic()
  363. },
  364. handleSizeChangeCustom(val){
  365. this.paramsCustom.pageSize = val
  366. this.getImageListCustom()
  367. },
  368. handleCurrentChangeCustom(val){
  369. this.paramsCustom.page = val
  370. this.getImageListCustom()
  371. },
  372. handleSizeChangeStar(val){
  373. this.paramsStar.pageSize = val
  374. this.getImageListStar()
  375. },
  376. handleCurrentChangeStar(val){
  377. this.paramsStar.page = val
  378. this.getImageListStar()
  379. },
  380. getImageListPublic(){
  381. this.loadingPublic = true
  382. this.$axios.get('/explore/images/public',{
  383. params:this.paramsPublic
  384. }).then((res)=>{
  385. console.log("res",res.data)
  386. this.totalNumPublic = res.data.count
  387. this.tableDataPublic = res.data.images
  388. this.loadingPublic = false
  389. })
  390. },
  391. getImageListCustom(){
  392. this.loadingCustom = true
  393. this.$axios.get('/explore/images/custom',{
  394. params:this.paramsCustom
  395. }).then((res)=>{
  396. console.log("res",res)
  397. this.totalNumCustom = res.data.count
  398. this.tableDataCustom = res.data.images
  399. this.loadingCustom = false
  400. })
  401. },
  402. getImageListStar(){
  403. this.loadingStar = true
  404. this.$axios.get('/explore/images/star',{
  405. params:this.paramsStar
  406. }).then((res)=>{
  407. console.log("res",res)
  408. this.totalNumStar = res.data.count
  409. this.tableDataStar = res.data.images
  410. this.loadingStar = false
  411. })
  412. },
  413. deleteImage(id){
  414. this.$axios.delete('/image/'+id).then((res)=>{
  415. console.log(res)
  416. this.getImageListCustom()
  417. })
  418. },
  419. eidtImage(id){
  420. location.href = `/image/${id}/imageSquare`
  421. },
  422. copyUrl(url){
  423. const cInput = document.createElement('input')
  424. cInput.value = url
  425. document.body.appendChild(cInput)
  426. cInput.select()
  427. document.execCommand('Copy')
  428. cInput.remove()
  429. },
  430. searchName(){
  431. if(this.activeName=='first'){
  432. this.paramsPublic.q = this.search
  433. this.paramsPublic.page = 1
  434. this.getImageListPublic()
  435. }
  436. if(this.activeName=='second'){
  437. this.paramsCustom.q = this.search
  438. this.paramsCustom.page = 1
  439. this.getImageListCustom()
  440. }
  441. if(this.activeName=='third'){
  442. this.paramsStar.q = this.search
  443. this.paramsStar.page = 1
  444. this.getImageListStar()
  445. }
  446. }
  447. },
  448. filters:{
  449. clearP(value){
  450. if(!value) return ''
  451. const reg = /\<\/?p\>/g;
  452. value = value.replace(reg,'')
  453. return value
  454. },
  455. transformType(val){
  456. if(val==0){
  457. return "GPU"
  458. }
  459. },
  460. transformPravite(val){
  461. if(val){
  462. return "私有"
  463. }else{
  464. return "公开"
  465. }
  466. },
  467. transformTimestamp(timestamp){
  468. // let a = new Date(timestamp).getTime();
  469. const date = new Date(parseInt(timestamp) * 1000);
  470. const Y = date.getFullYear() + '-';
  471. const M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-';
  472. const D = (date.getDate() < 10 ? '0'+date.getDate() : date.getDate()) + ' ';
  473. const h = (date.getHours() < 10 ? '0'+date.getHours() : date.getHours()) + ':';
  474. const m = (date.getMinutes() <10 ? '0'+date.getMinutes() : date.getMinutes()) + ':' ;
  475. const s = (date.getSeconds() <10 ? '0'+date.getSeconds() : date.getSeconds()) ; // 秒
  476. const dateString = Y + M + D + h + m + s;
  477. // console.log('dateString', dateString); // > dateString 2021-07-06 14:23
  478. return dateString;
  479. },
  480. },
  481. watch:{
  482. search(val){
  483. if(!val && this.activeName=='first'){
  484. this.paramsPublic.q = val
  485. this.getImageListPublic()
  486. }
  487. if(!val && this.activeName=='second'){
  488. this.paramsCustom.q = val
  489. this.getImageListCustom()
  490. }
  491. if(!val && this.activeName=='third'){
  492. this.paramsStar.q = val
  493. this.getImageListStar()
  494. }
  495. }
  496. },
  497. mounted() {
  498. this.getImageListPublic()
  499. },
  500. created() {
  501. }
  502. };
  503. </script>
  504. <style scoped>
  505. .header-wrapper {
  506. background-color: #f5f5f6;
  507. padding-top: 15px;
  508. }
  509. .image_text{
  510. padding:25px 0 55px 0 ;
  511. }
  512. #header{
  513. position: relative;
  514. top:-40px;
  515. }
  516. .el-dropdown-menu__item--divided{
  517. border-top: 1px solid blue;
  518. }
  519. .el-table thead{
  520. background-color: #f5f5f6;
  521. }
  522. /deep/ .el-tabs__item:hover{
  523. color: #000;
  524. font-weight: 500;
  525. }
  526. /deep/ .el-tabs__item.is-active {
  527. color: #000;
  528. font-weight: 500;
  529. }
  530. /deep/ .el-tabs__active-bar{
  531. background-color:#000
  532. }
  533. /deep/ .el-pagination.is-background .el-pager li:not(.disabled).active {
  534. background-color: #5bb973;
  535. color: #FFF;
  536. }
  537. /deep/ .el-pagination.is-background .el-pager li.active {
  538. color: #fff;
  539. cursor: default;
  540. }
  541. /deep/ .el-pagination.is-background .el-pager li:hover {
  542. color: #5bb973;
  543. }
  544. /deep/ .el-pagination.is-background .el-pager li:not(.disabled):hover {
  545. color: #5bb973;
  546. }
  547. /deep/ .el-pagination.is-background .el-pager li:not(.disabled).active:hover {
  548. background-color: #5bb973;
  549. color: #FFF;
  550. }
  551. /deep/ .el-pager li.active {
  552. color: #08C0B9;
  553. cursor: default;
  554. }
  555. /deep/ .el-pagination .el-pager li:hover {
  556. color: #08C0B9;
  557. }
  558. /deep/ .el-pagination .el-pager li:not(.disabled):hover {
  559. color: #08C0B9;
  560. }
  561. /* /deep/ .el-pagination.is-background .el-pager li:not(.disabled).active{
  562. background-color: #5bb973;
  563. color: #000;
  564. } */
  565. /* /deep/ .el-pager li:hover{
  566. color: #000;
  567. } */
  568. #success{
  569. background-color: #5bb973;
  570. color: white;
  571. }
  572. .text-over{
  573. overflow: hidden;
  574. text-overflow: ellipsis;
  575. vertical-align: middle;
  576. white-space: nowrap;
  577. }
  578. .image_title{
  579. display: inline-block;
  580. width: 80%;
  581. cursor: default;
  582. color: rgb(66, 98, 144);
  583. }
  584. .image_desc{
  585. -webkit-line-clamp: 2;
  586. -webkit-box-orient: vertical;
  587. display: -webkit-box;
  588. text-overflow: ellipsis;
  589. overflow: hidden;
  590. }
  591. .heart-stroke{
  592. stroke: #666;
  593. stroke-width: 2;
  594. fill: #fff
  595. }
  596. </style>