1
0

album.vue 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. <template>
  2. <view class="app-page">
  3. <view v-if="loading != 'success'" class="loading-wrap">
  4. <view v-if="loading == 'loading'" class="loading">
  5. <view class="loading-icon flex flex-center"><text class="e-loading-icon iconfont icon-loading"></text></view>
  6. <view class="loadig-text ">相册正在努力加载中啦~</view>
  7. </view>
  8. <tm-empty v-else icon="icon-shiliangzhinengduixiang-" color="red" label="啊偶,加载失败了呢~">
  9. <tm-button theme="red" :shadow="0" size="m" @click="fnRefresh()">刷新试试</tm-button>
  10. </tm-empty>
  11. </view>
  12. <!-- 内容区域 -->
  13. <view v-else class="app-page-content">
  14. <view v-if="dataList.length == 0" color="light-blue" class="content-empty flex flex-center">
  15. <tm-empty icon="icon-shiliangzhinengduixiang-" label="相册暂时还没有数据~">
  16. <tm-button :shadow="0" size="m" theme="light-blue" @click="fnRefresh()">刷新试试</tm-button>
  17. </tm-empty>
  18. </view>
  19. <block v-else>
  20. <swiper
  21. class="swiper-album"
  22. :current="swiperIndex"
  23. :acceleration="true"
  24. :circular="true"
  25. :vertical="false"
  26. :indicator-dots="false"
  27. :autoplay="false"
  28. @change="fnOnChange"
  29. >
  30. <block v-for="(item, index) in dataList" :key="index">
  31. <swiper-item class="swiper-album-item">
  32. <view class="scroll-wrap">
  33. <view class="card">
  34. <cache-image
  35. class="card-image"
  36. width="100%"
  37. height="46vh"
  38. radius="12rpx"
  39. :url="item.image"
  40. :fileMd5="item.image"
  41. mode="aspectFill"
  42. @on-click="fnOnPreview(item)"
  43. ></cache-image>
  44. <view v-if="item.description" class="card-desc">{{ item.description }}</view>
  45. <view v-else class="card-desc is-empty flex flex-col">
  46. <view class="text-grey-darken-1">该照片没有记录任何信息</view>
  47. <view class="text-size-m mt-24 text-grey-darken-1">记录一下拍照的瞬间,会更精彩哟</view>
  48. </view>
  49. </view>
  50. </view>
  51. </swiper-item>
  52. </block>
  53. </swiper>
  54. <view class="tabbar">
  55. <view class="pre" @click="fnChange(false)">
  56. <text class="icon"><text class="iconfont icon-arrow-left"></text></text>
  57. <text class="text">上一张</text>
  58. </view>
  59. <view class="refresh" @click="fnRefresh()">
  60. <text class="refresh-text">点击</text>
  61. <text class="refresh-heart iconfont icon-diagnose"></text>
  62. <text class="refresh-text">刷新</text>
  63. </view>
  64. <view class="next" @click="fnChange(true)">
  65. <text class="text">下一张</text>
  66. <text class="icon"><text class="iconfont icon-arrow-right"></text></text>
  67. </view>
  68. </view>
  69. </block>
  70. </view>
  71. </view>
  72. </template>
  73. <script>
  74. import LoveConfig from '@/config/love.config.js';
  75. import throttle from '@/utils/throttle.js';
  76. import tmButton from '@/tm-vuetify/components/tm-button/tm-button.vue';
  77. import tmFlotbutton from '@/tm-vuetify/components/tm-flotbutton/tm-flotbutton.vue';
  78. import tmTranslate from '@/tm-vuetify/components/tm-translate/tm-translate.vue';
  79. import tmEmpty from '@/tm-vuetify/components/tm-empty/tm-empty.vue';
  80. export default {
  81. components: {
  82. tmButton,
  83. tmFlotbutton,
  84. tmTranslate,
  85. tmEmpty
  86. },
  87. data() {
  88. return {
  89. loading: 'loading',
  90. loveConfig: LoveConfig,
  91. queryParams: {
  92. size: 99,
  93. page: 0,
  94. sort: 'takeTime',
  95. team: LoveConfig.albumKeyName
  96. },
  97. result: {},
  98. dataList: [],
  99. cache: {
  100. dataList: [],
  101. total: 0
  102. },
  103. swiperIndex: 0,
  104. tabbar: {
  105. list: []
  106. }
  107. };
  108. },
  109. onLoad() {
  110. this.fnSetPageTitle('恋爱相册');
  111. },
  112. created() {
  113. this.fnGetData();
  114. },
  115. onPullDownRefresh() {
  116. this.fnRefresh();
  117. },
  118. methods: {
  119. fnRefresh() {
  120. this.queryParams.page = 0;
  121. this.fnGetData();
  122. },
  123. fnGetData() {
  124. this.loading = 'loading';
  125. this.$httpApi
  126. .getPhotoListByPage(this.queryParams)
  127. .then(res => {
  128. if (res.status == 200) {
  129. this.loading = 'success';
  130. if (res.data.content.length != 0) {
  131. const _list = res.data.content.map((item, index) => {
  132. item['image'] = this.$utils.checkImageUrl(item.thumbnail);
  133. item['takeTime'] = this.$tm.dayjs(item['takeTime']).format('DD/MM/YYYY');
  134. return item;
  135. });
  136. this.dataList = _list;
  137. this.swiperIndex = 0;
  138. }
  139. } else {
  140. this.loading = 'error';
  141. uni.$tm.toast('加载失败,请下拉刷新重试!');
  142. }
  143. })
  144. .catch(err => {
  145. console.error(err);
  146. this.loading = 'error';
  147. uni.$tm.toast('加载失败,请下拉刷新重试!');
  148. })
  149. .finally(() => {
  150. setTimeout(() => {
  151. uni.stopPullDownRefresh();
  152. }, 200);
  153. });
  154. },
  155. // 缓存数据
  156. fnCacheDataList(dataList) {
  157. if (this.queryParams.page == 0) {
  158. this.cache.dataList = dataList;
  159. } else {
  160. this.cache.dataList = [...this.cache.dataList, ...dataList];
  161. }
  162. },
  163. fnOnPreview(item) {
  164. uni.previewImage({
  165. current: item.image,
  166. urls: this.dataList.map(x => x.image)
  167. });
  168. },
  169. fnOnChange(e) {
  170. this.swiperIndex = e.detail.current;
  171. },
  172. fnChange(isNext) {
  173. throttle(() => {
  174. if (isNext) {
  175. if (this.swiperIndex == this.dataList.length - 1) {
  176. this.swiperIndex = 0;
  177. } else {
  178. this.swiperIndex += 1;
  179. }
  180. } else {
  181. if (this.swiperIndex == 0) {
  182. this.swiperIndex = this.dataList.length - 1;
  183. } else {
  184. this.swiperIndex -= 1;
  185. }
  186. }
  187. });
  188. }
  189. }
  190. };
  191. </script>
  192. <style lang="scss" scoped>
  193. .app-page {
  194. width: 100vw;
  195. min-height: 100vh;
  196. display: flex;
  197. flex-direction: column;
  198. box-sizing: border-box;
  199. padding: 24rpx 0;
  200. padding-bottom: 144rpx;
  201. background: linear-gradient(
  202. -135deg,
  203. rgba(247, 149, 51, 0.1),
  204. rgba(243, 112, 85, 0.1) 15%,
  205. rgba(239, 78, 123, 0.1) 30%,
  206. rgba(161, 102, 171, 0.1) 44%,
  207. rgba(80, 115, 184, 0.1) 58%,
  208. rgba(16, 152, 173, 0.1) 72%,
  209. rgba(7, 179, 155, 0.1) 86%,
  210. rgba(109, 186, 130, 0.1)
  211. );
  212. }
  213. .app-page-content {
  214. }
  215. .loading-wrap {
  216. width: 100vw;
  217. height: 60vh;
  218. display: flex;
  219. flex-direction: column;
  220. align-items: center;
  221. justify-content: center;
  222. box-sizing: border-box;
  223. padding: 36rpx;
  224. ::v-deep {
  225. .tm-icons {
  226. margin-right: -20rpx;
  227. }
  228. }
  229. }
  230. .e-loading-icon {
  231. font-size: 120rpx;
  232. // color: #f88ca2;
  233. color: #56bbf9;
  234. }
  235. .loadig-text {
  236. margin-top: 28rpx;
  237. font-size: 28rpx;
  238. // color: #f88ca2;
  239. color: #56bbf9;
  240. }
  241. .content-empty {
  242. width: 100%;
  243. height: 60vh;
  244. }
  245. .swiper-album {
  246. width: 100vw;
  247. height: calc(100vh - 24rpx - 144rpx);
  248. }
  249. .swiper-album-item {
  250. height: 100%;
  251. display: flex;
  252. align-items: center;
  253. justify-content: center;
  254. box-sizing: border-box;
  255. padding: 36rpx;
  256. /* #ifdef H5 */
  257. padding-bottom: 110rpx;
  258. /* #endif */
  259. /* #ifndef H5 */
  260. padding-bottom: 60rpx;
  261. /* #endif */
  262. }
  263. .scroll-wrap {
  264. width: 100%;
  265. height: 100%;
  266. box-sizing: border-box;
  267. padding: 36rpx;
  268. background-color: #ffffff;
  269. border-radius: 12rpx;
  270. box-shadow: 0rpx 4rpx 24rpx rgba(0, 0, 0, 0.03);
  271. }
  272. .card {
  273. display: flex;
  274. flex-direction: column;
  275. width: 100%;
  276. // height: 65vh;
  277. height: 100%;
  278. max-height: 100%;
  279. border-radius: 12rpx;
  280. background-color: #ffffff;
  281. box-sizing: border-box;
  282. // box-shadow: 0rpx 4rpx 24rpx rgba(0, 0, 0, 0.03);
  283. overflow: hidden;
  284. overflow-y: auto;
  285. ::v-deep {
  286. .cache-image {
  287. height: initial !important;
  288. }
  289. }
  290. &-image {
  291. width: 100%;
  292. height: initial !important;
  293. border-radius: 12rpx;
  294. }
  295. &-desc {
  296. margin-top: 24rpx;
  297. line-height: 1.6;
  298. font-size: 30rpx;
  299. color: rgba(26, 26, 26, 0.9);
  300. &.is-empty {
  301. display: flex;
  302. align-items: center;
  303. justify-content: center;
  304. flex-grow: 1;
  305. font-size: 32rpx;
  306. }
  307. }
  308. }
  309. .tabbar {
  310. width: 90vw;
  311. position: fixed;
  312. left: 50%;
  313. bottom: 40rpx;
  314. transform: translateX(-50%);
  315. border-radius: 25rpx;
  316. box-sizing: border-box;
  317. padding: 24rpx;
  318. display: flex;
  319. align-items: center;
  320. justify-content: space-between;
  321. // background-color: rgba(0, 0, 0, 0.5);
  322. background-color: #ffffff;
  323. color: #333;
  324. box-shadow: 0rpx 4rpx 24rpx rgba(0, 0, 0, 0.05);
  325. .refresh {
  326. animation: refreshAni 6s ease-in-out infinite;
  327. color: #56bbf9;
  328. &-heart {
  329. font-size: 42rpx;
  330. color: inherit;
  331. margin: 0 6rpx;
  332. }
  333. &-text {
  334. font-size: 24rpx;
  335. }
  336. }
  337. .pre {
  338. color: #56bbf9;
  339. transition: transform 0.1s ease-in-out;
  340. &:hover {
  341. transform: scale(1.05);
  342. }
  343. .text {
  344. padding-left: 12rpx;
  345. }
  346. }
  347. .next {
  348. color: #f88ca2;
  349. transition: transform 0.1s ease-in-out;
  350. &:hover {
  351. transform: scale(1.03);
  352. }
  353. .text {
  354. padding-right: 12rpx;
  355. }
  356. }
  357. }
  358. @keyframes refreshAni {
  359. 0% {
  360. color: #f88ca2;
  361. }
  362. 50% {
  363. color: #56bbf9;
  364. }
  365. 100% {
  366. color: #f88ca2;
  367. }
  368. }
  369. </style>