index.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545
  1. <template>
  2. <div class="big-screen-list-wrap">
  3. <div class="top-search-wrap">
  4. <el-input
  5. v-model="searchKey"
  6. class="bs-el-input"
  7. placeholder="请输入图片名称"
  8. prefix-icon="el-icon-search"
  9. clearable
  10. @clear="reSearch"
  11. @keyup.enter.native="reSearch"
  12. />
  13. <el-select
  14. v-model="extend"
  15. class="bs-el-select"
  16. popper-class="bs-el-select"
  17. placeholder="请选择图片格式"
  18. clearable
  19. @change="reSearch"
  20. >
  21. <el-option
  22. v-for="item in options"
  23. :key="item.value"
  24. :label="item.label"
  25. :value="item.value"
  26. />
  27. </el-select>
  28. <el-button
  29. size="small"
  30. style="margin-right: 20px"
  31. type="primary"
  32. @click="reSearch"
  33. >
  34. 搜索
  35. </el-button>
  36. <el-upload
  37. class="upload-demo"
  38. :action="upLoadUrl"
  39. :headers="headers"
  40. :data="{ module: code }"
  41. :on-success="uploadSuccess"
  42. :on-error="uploadError"
  43. multiple
  44. :file-list="fileList"
  45. :show-file-list="false"
  46. >
  47. <el-button
  48. size="small"
  49. type="primary"
  50. >
  51. 上传资源
  52. </el-button>
  53. </el-upload>
  54. </div>
  55. <div
  56. v-if="list.length !== 0"
  57. v-loading="loading"
  58. class="list-wrap bs-scrollbar"
  59. element-loading-text="加载中"
  60. :style="{
  61. display: gridComputed ? 'grid' : 'flex',
  62. justifyContent: gridComputed ? 'space-around' : 'flex-start'
  63. }"
  64. >
  65. <!-- <div v-if="list.length !== 0"> -->
  66. <div
  67. v-for="screen in list"
  68. :key="screen.id"
  69. class="big-screen-card-wrap"
  70. :style="{
  71. width: gridComputed ? 'auto' : '290px'
  72. }"
  73. >
  74. <div class="big-screen-card-inner">
  75. <div class="screen-card__hover">
  76. <div class="screen-card__hover-box">
  77. <div class="preview">
  78. <div
  79. class="screen-card__oper-label circle"
  80. @click="preview(screen)"
  81. >
  82. <span>预览</span>
  83. </div>
  84. <div
  85. class="circle"
  86. @click="downLoad(screen)"
  87. >
  88. <span>下载</span>
  89. </div>
  90. <div
  91. class="circle"
  92. @click="del(screen)"
  93. >
  94. <span>删除</span>
  95. </div>
  96. <div
  97. class="circle"
  98. @click="copy(screen)"
  99. >
  100. <span>链接</span>
  101. </div>
  102. </div>
  103. </div>
  104. </div>
  105. <div class="big-screen-card-img">
  106. <el-image
  107. :src="screen.url"
  108. fit="contain"
  109. style="width: 100%; height: 100%"
  110. >
  111. <div
  112. slot="placeholder"
  113. class="image-slot"
  114. >
  115. 加载中···
  116. </div>
  117. </el-image>
  118. </div>
  119. <div class="big-screen-bottom">
  120. <div
  121. class="left-bigscreen-title"
  122. :title="screen.originalName"
  123. >
  124. {{ screen.originalName }}
  125. </div>
  126. </div>
  127. </div>
  128. </div>
  129. </div>
  130. <div
  131. v-else
  132. class="empty"
  133. >
  134. 暂无数据
  135. </div>
  136. <div class="footer-pagination-wrap">
  137. <!-- <div class="footer-pagination-wrap-text">
  138. 总共 {{ totalCount }} 个项目
  139. </div> -->
  140. <div class="bs-pagination">
  141. <el-pagination
  142. class="bs-el-pagination"
  143. popper-class="bs-el-pagination"
  144. background
  145. layout="total, prev, pager, next, sizes"
  146. :page-size="size"
  147. prev-text="上一页"
  148. next-text="下一页"
  149. :total="totalCount"
  150. :page-sizes="[10, 20, 50, 100]"
  151. :current-page="current"
  152. @current-change="currentChangeHandle"
  153. @size-change="sizeChangeHandle"
  154. />
  155. </div>
  156. </div>
  157. <!-- 新增或编辑弹窗 -->
  158. <EditForm
  159. ref="EditForm"
  160. @refreshData="reSearch"
  161. />
  162. </div>
  163. </template>
  164. <script>
  165. import { get, post, download } from 'packages/js/utils/http'
  166. import { pageMixins } from 'packages/js/mixins/page'
  167. import EditForm from './EditForm.vue'
  168. export default {
  169. name: 'BigScreenList',
  170. mixins: [pageMixins],
  171. props: {
  172. type: {
  173. type: String,
  174. default: 'bigScreen' // bigScreen | template
  175. },
  176. catalogInfo: {
  177. type: Object,
  178. default: () => {}
  179. }
  180. },
  181. components: { EditForm },
  182. data () {
  183. return {
  184. upLoadUrl:
  185. window.BS_CONFIG?.httpConfigs?.baseURL + '/bigScreen/file/upload',
  186. searchKey: '',
  187. extend: '',
  188. options: [],
  189. list: [],
  190. fileUploadParam: {},
  191. headers: {
  192. ...window.BS_CONFIG?.httpConfigs?.headers
  193. },
  194. fileList: [],
  195. defaultImg: require('./images/defaultImg.png'),
  196. loading: false
  197. }
  198. },
  199. computed: {
  200. code () {
  201. return this.catalogInfo?.page?.code
  202. },
  203. gridComputed () {
  204. return this.list.length > 3
  205. }
  206. },
  207. watch: {
  208. code (value) {
  209. this.current = 1
  210. this.getDataList()
  211. }
  212. },
  213. mounted () {
  214. this.getOptions()
  215. this.getDataList()
  216. },
  217. methods: {
  218. uploadError () {
  219. this.$message({
  220. type: 'error',
  221. message: '上传失败'
  222. })
  223. },
  224. uploadSuccess (response, file, fileList) {
  225. if (response.code === 200) {
  226. this.$message({
  227. type: 'success',
  228. message: '上传成功'
  229. })
  230. this.getDataList()
  231. } else {
  232. this.$message({
  233. type: 'error',
  234. message: response.msg
  235. })
  236. }
  237. },
  238. getOptions () {
  239. get('/bigScreen/file/getAllFileSuffix').then((data) => {
  240. this.options = []
  241. this.options.push({ label: '全部', value: '' })
  242. data.forEach((item) => this.options.push({ label: item, value: item }))
  243. })
  244. },
  245. getDataList () {
  246. this.loading = true
  247. get('/bigScreen/file', {
  248. module: this.catalogInfo.page.code,
  249. current: this.current,
  250. size: this.size,
  251. extension: this.extend,
  252. searchKey: this.searchKey
  253. })
  254. .then((data) => {
  255. this.list = data.list
  256. this.totalCount = data.totalCount
  257. })
  258. .finally(() => {
  259. this.loading = false
  260. })
  261. },
  262. preview (screen) {
  263. window.open(screen.url, '_blank')
  264. },
  265. downLoad (screen) {
  266. download(`/bigScreen/file/download/${screen.id}`)
  267. },
  268. del (screen) {
  269. this.$confirm('确定删除该资源?', '提示', {
  270. confirmButtonText: '确定',
  271. cancelButtonText: '取消',
  272. type: 'warning',
  273. customClass: 'bs-el-message-box'
  274. })
  275. .then(async () => {
  276. post(`/bigScreen/file/delete/${screen.id}`)
  277. .then(() => {
  278. this.$message({
  279. type: 'success',
  280. message: '删除成功'
  281. })
  282. this.getDataList()
  283. })
  284. .catch(() => {
  285. this.$message({
  286. type: 'error',
  287. message: '删除失败!'
  288. })
  289. })
  290. })
  291. .catch()
  292. },
  293. copy (screen) {
  294. this.$message.success('复制成功')
  295. const transfer = document.createElement('input')
  296. document.body.appendChild(transfer)
  297. transfer.value = screen.url // 这里表示想要复制的内容
  298. transfer.focus()
  299. transfer.select()
  300. if (document.execCommand('copy')) {
  301. document.execCommand('copy')
  302. }
  303. transfer.blur()
  304. transfer.style.display = 'none'
  305. }
  306. }
  307. }
  308. </script>
  309. <style lang="scss" scoped>
  310. @import '../assets/style/bsTheme.scss';
  311. .big-screen-list-wrap {
  312. position: relative;
  313. height: 100%;
  314. padding: 16px;
  315. color: #9ea9b2;
  316. margin:0 16px;
  317. background-color: var(--bs-background-2) !important;
  318. .top-search-wrap {
  319. display: flex;
  320. align-items: center;
  321. justify-content: flex-end;
  322. margin-bottom: 12px;
  323. .el-input {
  324. width: 200px;
  325. margin-right: 20px;
  326. /deep/.el-input__inner {
  327. background-color: var(--bs-background-1) !important;
  328. }
  329. }
  330. .el-select {
  331. margin-right: 20px;
  332. /deep/.el-input__inner {
  333. background-color: var(--bs-background-1) !important;
  334. }
  335. }
  336. }
  337. .list-wrap {
  338. /* display: grid; */
  339. overflow: auto;
  340. // 间隙自适应
  341. justify-content: space-around;
  342. max-height: calc(100vh - 304px);
  343. display: grid;
  344. grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  345. grid-gap: 15px;
  346. // /deep/ .el-loading-mask {
  347. // display: flex;
  348. // align-items: center;
  349. // justify-content: center;
  350. // height: calc(100vh - 260px) !important;
  351. // z-index: 999;
  352. // top: 50px;
  353. // }
  354. .big-screen-card-wrap {
  355. position: relative;
  356. height: 230px;
  357. cursor: pointer;
  358. &:hover {
  359. .screen-card__hover {
  360. height: 230px;
  361. }
  362. }
  363. .screen-card__hover {
  364. position: absolute;
  365. z-index: 999;
  366. top: 0;
  367. right: 0;
  368. left: 0;
  369. display: flex;
  370. overflow: hidden;
  371. align-items: center;
  372. justify-content: center;
  373. height: 0;
  374. transition: height 0.4s;
  375. background: #00000099;
  376. .screen-card__hover-box {
  377. position: absolute;
  378. width: 100%;
  379. height: 100%;
  380. background: #00000080;
  381. display: flex;
  382. overflow: hidden;
  383. align-items: center;
  384. justify-content: center;
  385. }
  386. .preview {
  387. display: flex;
  388. flex-direction: row;
  389. justify-content: space-evenly;
  390. width: 100%;
  391. cursor: pointer;
  392. color: var(--bs-el-color-primary);
  393. .circle {
  394. position: relative;
  395. display: flex;
  396. align-items: center;
  397. justify-content: center;
  398. width: 40px;
  399. height: 40px;
  400. border: 1px solid var(--bs-el-color-primary);
  401. border-radius: 50%;
  402. &:hover {
  403. color: #fff;
  404. background: var(--bs-el-color-primary);
  405. }
  406. span {
  407. font-size: 12px;
  408. }
  409. }
  410. }
  411. }
  412. .big-screen-card-inner {
  413. overflow: hidden;
  414. width: 100%;
  415. height: 100%;
  416. cursor: pointer;
  417. background-color: var(--bs-background-2);
  418. box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.1);
  419. color: var(--bs-el-title);
  420. border: 1px solid var(--bs-background-1);
  421. &:hover {
  422. color: var(--bs-el-text);
  423. border: 1px solid var(--bs-el-color-primary);
  424. }
  425. .add-big-screen-card-text {
  426. color: var(--bs-el-color-primary);
  427. font-size: 24px;
  428. }
  429. .big-screen-card-img {
  430. width: 100%;
  431. height: 180px;
  432. img {
  433. width: 100%;
  434. height: 100%;
  435. object-fit: cover;
  436. }
  437. /deep/.image-slot {
  438. height: 100%;
  439. background-color: var(--bs-background-2);
  440. display: flex;
  441. align-items: center;
  442. justify-content: center;
  443. }
  444. /deep/.el-image__error {
  445. background-color: #1d1d1d;
  446. }
  447. }
  448. .big-screen-bottom {
  449. display: flex;
  450. align-items: center;
  451. flex-direction: row;
  452. justify-content: space-between;
  453. box-sizing: border-box;
  454. width: 100%;
  455. /*height: 26px;*/
  456. padding: 0 10px;
  457. height: calc(100% - 180px);
  458. color: var(--bs-el-title);
  459. background-color: var(--bs-background-2);
  460. .left-bigscreen-title {
  461. font-size: 14px;
  462. overflow: hidden;
  463. width: 100%;
  464. white-space: nowrap;
  465. text-overflow: ellipsis;
  466. }
  467. .right-bigscreen-time-title {
  468. font-size: 14px;
  469. overflow: hidden;
  470. width: 140px;
  471. white-space: nowrap;
  472. text-overflow: ellipsis;
  473. }
  474. }
  475. .big-screen-card-text {
  476. font-size: 14px;
  477. padding: 10px;
  478. text-align: center;
  479. color: #333;
  480. }
  481. }
  482. .big-screen-card-inner-add {
  483. display: flex;
  484. align-items: center;
  485. justify-content: center;
  486. }
  487. }
  488. }
  489. .el-loading-parent--relative {
  490. position: unset !important;
  491. }
  492. .footer-pagination-wrap {
  493. // position: absolute;
  494. // bottom: 10px;
  495. // display: flex;
  496. // align-items: center;
  497. // justify-content: flex-end;
  498. // width: 100%;
  499. position: absolute;
  500. bottom: 16px;
  501. right: 12px;
  502. // padding: 0 16px;
  503. }
  504. }
  505. .bs-pagination {
  506. ::v-deep .el-input__inner {
  507. width: 110px !important;
  508. border: none;
  509. background: var(--bs-el-background-1);
  510. }
  511. }
  512. .empty {
  513. width: 100%;
  514. height: 70%;
  515. display: flex;
  516. justify-content: center;
  517. align-items: center;
  518. }
  519. </style>