detail - 副本.vue 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. <!-- html -->
  2. <template>
  3. <view style="overflow: hidden;">
  4. <u-checkbox-group @change="checkboxGroupChange" max=9>
  5. <view class="container">
  6. <view class="left">
  7. <view class="posive" v-for="(item,index) in leftList" :key="index">
  8. <image :src="item.url" alt="" mode="widthFix" @click="previewImg(item)" />
  9. <!-- <view v-if="upload" class="collected">
  10. <u-checkbox v-model="item.checked" :name="item.src" shape="circle" active-color="#3D6EF6" size="16" icon-size="8" />
  11. </view> -->
  12. </view>
  13. </view>
  14. <view class="right">
  15. <view class="posive" v-for="(item,index) in rightList" :key="index">
  16. <image :src="item.url" alt="" mode="widthFix" @click="previewImg(item)" />
  17. <!-- <view v-if="upload" class="collected">
  18. <u-checkbox v-model="item.checked" :name="item.src" shape="circle" active-color="#3D6EF6" size="16" icon-size="8" />
  19. </view> -->
  20. </view>
  21. </view>
  22. <!-- <view v-show="!upload" class="fixed" @click="upload = true, clearUp()">
  23. 下载
  24. </view> -->
  25. <view v-show="upload" class="fixed2 flexS">
  26. <view class="left">
  27. 已选择<text>{{ checkUrl.length}}</text>张
  28. </view>
  29. <view class="flex">
  30. <view class="upload" @click="downloadImgs">
  31. 立即下载
  32. </view>
  33. <view class="quxiao" @click="upload = false">
  34. 取消
  35. </view>
  36. </view>
  37. </view>
  38. </view>
  39. <u-loadmore
  40. v-if="nomore"
  41. dashed
  42. status="nomore"
  43. nomore-text="没有更多啦~"
  44. />
  45. </u-checkbox-group>
  46. <u-overlay :show="show" @click="show = false" :opacity="1">
  47. <swiper :autoplay="false" :duration="350" :current="current" class="swiper">
  48. <swiper-item v-for="(item,index) in list">
  49. <img :src="item.url" alt="" />
  50. <view v-if="item.master" class="btn" @tap.stop="showMaster(item, index)">
  51. 查看原图
  52. </view>
  53. </swiper-item>
  54. </swiper>
  55. </u-overlay>
  56. </view>
  57. </template>
  58. <script>
  59. import { GetImgDetail } from '../../api/index.js';
  60. export default {
  61. data() {
  62. return {
  63. upload: false,
  64. show: false,
  65. list: [],
  66. checkUrl: [],
  67. nomore: false,
  68. current: 0,
  69. leftList: [],// 初始化左右盒子
  70. rightList: [],
  71. preList: [],
  72. leftH: 0,// 初始化左右盒子高度
  73. rightH: 0,
  74. params: {
  75. id: '',
  76. page_index: 1,
  77. page_size: 15,
  78. type: 1
  79. },
  80. totalPage: 0
  81. }
  82. },
  83. onLoad(option) {
  84. if (option.title) {
  85. uni.setNavigationBarTitle({
  86. title: option.title
  87. });
  88. }
  89. this.params.id = option.id
  90. this.getList()
  91. },
  92. onReachBottom() {
  93. this.more()
  94. },
  95. methods: {
  96. // 点击放大图片
  97. previewImg(item) {
  98. let i = this.list.findIndex(v => v.id == item.id)
  99. this.current = i
  100. this.show = true
  101. // this.stop()
  102. },
  103. showMaster(item, i) {
  104. this.list[i].url = item.img_url
  105. this.list[i].master = false
  106. },
  107. //禁止页面滑动
  108. stop(){
  109. var mo=function(e){e.preventDefault();};
  110. document.body.style.overflow='hidden';
  111. document.addEventListener("touchmove",mo,false);
  112. },
  113. /***取消滑动限制***/
  114. move(){
  115. var mo=function(e){e.preventDefault();};
  116. document.body.style.overflow='';//出现滚动条
  117. document.removeEventListener("touchmove",mo,false);
  118. },
  119. //获取列表
  120. getList(isMore) {
  121. uni.showLoading()
  122. GetImgDetail(this.params).then(res => {
  123. uni.hideLoading()
  124. if (res.code === 200) {
  125. const { list, total } = res.data
  126. if (list.length === 0) {
  127. uni.showToast({ title: '暂无内容', icon: 'none' })
  128. return false
  129. }
  130. this.totalPage = Math.ceil(Number(total) / 15)
  131. list.forEach(e=> {
  132. e.master = true
  133. })
  134. this.doList(list)
  135. this.list = isMore ? this.list.concat(list) : list
  136. } else {
  137. uni.showToast({ title: res.message || '获取列表失败', icon: 'none' })
  138. }
  139. })
  140. },
  141. //加载获取更多
  142. more() {
  143. if (this.params.page_index >= this.totalPage) {
  144. this.nomore = true
  145. return false
  146. }
  147. this.params.page_index++
  148. this.getList(true)
  149. },
  150. // 瀑布流
  151. doList(list) {
  152. const that = this
  153. list.forEach(res => {
  154. // 获取图片宽高
  155. uni.getImageInfo({
  156. src: res.url,
  157. success: (image) => {
  158. // 计算图片渲染高度
  159. let showH = (50 * image.height) / image.width
  160. // 判断左右盒子高度
  161. if(that.leftH <= that.rightH) {
  162. that.leftList.push(res)
  163. that.leftH += showH
  164. } else {
  165. that.rightList.push(res)
  166. that.rightH += showH
  167. }
  168. }
  169. })
  170. })
  171. },
  172. // 下载图片
  173. downloadImgs() {
  174. this.clicked = false
  175. if (this.checkUrl.length === 0) {
  176. this.clicked = true
  177. uni.showToast({
  178. title: '请选择需要保存的图片',
  179. icon: 'none'
  180. })
  181. return
  182. }
  183. if (this.checkUrl.length > 9) {
  184. this.clicked = true
  185. uni.showToast({
  186. title: '每次最多只能保存9张图片',
  187. icon: 'none'
  188. })
  189. return
  190. }
  191. var _this = this
  192. // 调用保存图片promise队列
  193. _this.queue(_this.checkUrl).then(res => {
  194. uni.hideLoading()
  195. // uni.showToast({
  196. // title: '下载完成'
  197. // })
  198. _this.imgList.forEach((item, i) => {
  199. item.checked = false
  200. })
  201. _this.checkUrl = []
  202. _this.clicked = true
  203. }).catch(err => {
  204. _this.checkUrl = []
  205. _this.clicked = true
  206. uni.hideLoading()
  207. })
  208. },
  209. // 队列
  210. queue(urls) {
  211. let promise = Promise.resolve()
  212. urls.forEach((url, index) => {
  213. promise = promise.then(() => {
  214. return this.download(url,index)
  215. })
  216. })
  217. return promise
  218. },
  219. // 下载
  220. download(url, index) {
  221. let length = this.checkUrl.length
  222. return new Promise((resolve, reject) => {
  223. uni.downloadFile({
  224. url: url,
  225. success: function(res) {
  226. var temp = res.tempFilePath
  227. var link = document.createElement('a')
  228. link.href = temp
  229. link.download = '图片' + index
  230. document.body.appendChild(link)
  231. link.click()
  232. uni.showLoading({
  233. title: '下载中(' + (index + 1) + '/' + length + ')'
  234. })
  235. resolve(res)
  236. },
  237. fail: function(err) {
  238. reject(err)
  239. }
  240. })
  241. })
  242. },
  243. // 清除已选项
  244. clearUp() {
  245. this.leftList.forEach((item, i) => {
  246. item.checked = false
  247. })
  248. this.rightList.forEach((item, i) => {
  249. item.checked = false
  250. })
  251. },
  252. // 选中任一checkbox时,由checkbox-group触发
  253. checkboxGroupChange(e) {
  254. this.checkUrl = e
  255. },
  256. }
  257. }
  258. </script>
  259. <style lang="scss" scoped>
  260. * { touch-action: pan-y; }
  261. page {
  262. background-color: #fff;
  263. padding-top: 20rpx;
  264. }
  265. .swiper {
  266. position: relative;
  267. left: 0;
  268. top: 0;
  269. width: 100%;
  270. height: 100%;
  271. overflow: hidden;
  272. img {
  273. position: absolute;
  274. left: 50%;
  275. top: 50%;
  276. -webkit-transform: translate(-50%,-50%);
  277. transform: translate(-50%,-50%);
  278. max-height: 100%;
  279. max-width: 100%;
  280. width: 100%;
  281. }
  282. .btn {
  283. position: absolute;
  284. bottom: 60rpx;
  285. left: 285rpx;
  286. width: 180rpx;
  287. height: 60rpx;
  288. line-height: 60rpx;
  289. border-radius: 36rpx 36rpx 36rpx 36rpx;
  290. border: 1rpx #FFFFFF solid;
  291. color: #FFFFFF;
  292. text-align: center;
  293. }
  294. }
  295. .container {
  296. padding: 0 24rpx;
  297. font-size: 14rpx;
  298. line-height: 24rpx;
  299. display: flex;
  300. justify-content: space-between;
  301. .right, .left{
  302. display: inline-block;
  303. width: 340rpx;
  304. vertical-align: top;
  305. }
  306. .left image, .right image{
  307. border-radius: 16rpx;
  308. width: 100%;
  309. margin-bottom: 24rpx;
  310. }
  311. .posive {
  312. position: relative;
  313. }
  314. .collected {
  315. border: 2rpx solid #3D6EF6;
  316. position: absolute;
  317. background-color: rgba(0, 0, 0, 0.4);
  318. border-radius: 50%;
  319. bottom: 40rpx;
  320. right: 16rpx;
  321. z-index: 10;
  322. }
  323. .fixed {
  324. width: 80rpx;
  325. height: 80rpx;
  326. border-radius: 50%;
  327. text-align: center;
  328. line-height: 80rpx;
  329. background: #3D6EF6;
  330. position: fixed;
  331. right: 24rpx;
  332. bottom: 40rpx;
  333. color: #fff;
  334. z-index: 100;
  335. }
  336. .fixed2 {
  337. position: fixed;
  338. right: 0;
  339. bottom: 0;
  340. width: 684rpx;
  341. height: 96rpx;
  342. background: #000000;
  343. border-radius: 0px 0px 0px 0px;
  344. // opacity: 0.5;
  345. background-color: rgba(000,000,000,0.5);
  346. padding: 0 32rpx;
  347. color: #FFFFFF;
  348. font-size: 28rpx;
  349. z-index: 100;
  350. .left {
  351. font-size: 32rpx;
  352. font-weight: bold;
  353. text {
  354. color: #3D6EF6;
  355. margin: 0 10rpx;
  356. }
  357. }
  358. .upload {
  359. width: 176rpx;
  360. height: 64rpx;
  361. background: #3D6EF6;
  362. border-radius: 32rpx 32rpx 32rpx 32rpx;
  363. text-align: center;
  364. line-height: 64rpx;
  365. }
  366. .quxiao {
  367. width: 120rpx;
  368. height: 64rpx;
  369. margin-left: 24rpx;
  370. border-radius: 32rpx 32rpx 32rpx 32rpx;
  371. opacity: 1;
  372. border: 2rpx solid #F5F5F5;
  373. text-align: center;
  374. line-height: 64rpx;
  375. }
  376. }
  377. }
  378. </style>