shopro-float-btn.vue 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. <template>
  2. <view class="" v-if="floatList && floatList.length">
  3. <view class="cu-modal" :class="{ show: showMask }" @tap="hideMask"></view>
  4. <!-- 悬浮按钮菜单 -->
  5. <view class="shopro-float-btn">
  6. <button class="wechat-btn u-reset-button" @tap="onBtn">
  7. <image class="wechat_img" :src="floatList.length == 1 ? floatList[0].btnimage : floatData.image" mode="widthFix"></image>
  8. </button>
  9. <view :class="showBtnList ? 'float--active' : 'float-list-box'">
  10. <view class="btn-img-box u-flex-col" @tap="onBtnItem(item)" v-for="item in floatList" :key="item.btnimage">
  11. <view class="btn-item u-flex-col u-row-center u-col-center">
  12. <image class="btn-img" :src="item.btnimage" mode="aspectFill"></image>
  13. <view class="btn-name">{{ item.name }}</view>
  14. </view>
  15. </view>
  16. </view>
  17. </view>
  18. <!-- 弹窗 -->
  19. <view class="cu-modal" :class="{ show: showModal }" @tap="showModal = false">
  20. <view class="cu-dialog" style="width: 610rpx;background: none;">
  21. <view class="img-box"><image class="modal-img" :src="modalImg" mode="aspectFit" @tap="saveImage(modalImg)"></image></view>
  22. </view>
  23. </view>
  24. </view>
  25. </template>
  26. <script>
  27. /**
  28. * 悬浮按钮,悬浮菜单。全局通用,数据为vuex初始化导入。
  29. * @property {Array} floatList - 悬浮按钮菜单数据列表
  30. */
  31. import { mapMutations, mapActions, mapState, mapGetters } from 'vuex';
  32. import Auth from '@/shopro/permission/index.js';
  33. export default {
  34. components: {},
  35. data() {
  36. return {
  37. showBtnList: false, //列表弹出
  38. modalImg: '', //子项图片弹出
  39. showModal: false, //modal层
  40. showMask: false,
  41. platform: this.$platform.get()
  42. };
  43. },
  44. props: {},
  45. computed: {
  46. ...mapGetters(['floatData']),
  47. // 悬浮按钮数据列表
  48. floatList() {
  49. if (this.floatData) {
  50. return this.floatData.list;
  51. }
  52. }
  53. },
  54. created() {},
  55. methods: {
  56. hideMask() {
  57. this.showBtnList = false;
  58. this.showMask = false;
  59. },
  60. // 点击悬浮按钮
  61. onBtn() {
  62. this.showMask = !this.showMask;
  63. if (this.floatList.length == 1) {
  64. this.modalImg = this.floatList[0].image;
  65. this.floatList[0].style == 2 ? this.$tools.routerTo(this.floatList[0].path) : (this.showModal = true);
  66. this.showMask = false;
  67. } else {
  68. this.showBtnList = !this.showBtnList;
  69. }
  70. },
  71. // 点击按钮菜单,如果悬浮按钮数据为一条,按钮图片为唯一菜单项图片和标题
  72. onBtnItem(item) {
  73. if (item.style == 2) {
  74. this.showMask = false;
  75. this.showModal = false;
  76. this.showBtnList = false;
  77. this.$tools.routerTo(item.path);
  78. } else {
  79. this.modalImg = item.image;
  80. this.showMask = false;
  81. this.showModal = true;
  82. this.showBtnList = false;
  83. !item.image && console.log(`%cerr:弹窗图片未配置`, 'color:green;background:yellow');
  84. }
  85. },
  86. saveImageToPhotosAlbum(path) {
  87. uni.saveImageToPhotosAlbum({
  88. filePath: path,
  89. success: res => {
  90. this.showMask = false;
  91. this.showModal = false;
  92. this.$u.toast('保存成功');
  93. },
  94. fail: err => {
  95. console.log(`图片保存失败:`, err);
  96. this.$u.toast('保存失败');
  97. }
  98. });
  99. },
  100. // 保存图片
  101. async saveImage(path) {
  102. let that = this;
  103. if (['wxOfficialAccount', 'H5'].includes(this.platform)) {
  104. this.$u.toast('长按图片保存');
  105. return false;
  106. }
  107. let authState = await new Auth('writePhotosAlbum').check();
  108. if (authState) {
  109. // #ifdef MP ||APP-VUE
  110. const res = await uni.downloadFile({
  111. url: this.$tools.checkMPUrl(path)
  112. });
  113. res[1].statusCode === 200 && this.saveImageToPhotosAlbum(res[1].tempFilePath);
  114. // #endif
  115. }
  116. }
  117. }
  118. };
  119. </script>
  120. <style lang="scss">
  121. .shopro-float-btn {
  122. position: fixed;
  123. bottom: calc(var(--window-bottom) + 100rpx);
  124. right: 30rpx;
  125. z-index: 9999;
  126. .float--active {
  127. position: absolute;
  128. bottom: 80rpx;
  129. right: 0;
  130. left: 0;
  131. margin: 0 auto;
  132. z-index: 10010;
  133. transform: scale(1);
  134. transition: all 0.2s linear;
  135. }
  136. .float-list-box {
  137. position: absolute;
  138. z-index: 10010;
  139. bottom: 0;
  140. right: 0;
  141. left: 0;
  142. margin: 0 auto;
  143. transform: scale(0);
  144. transform-origin: bottom;
  145. opacity: 0;
  146. transition: all 0.2s linear;
  147. }
  148. .btn-item {
  149. margin-bottom: 20rpx;
  150. .btn-img {
  151. width: 60rpx;
  152. height: 60rpx;
  153. }
  154. .btn-name {
  155. font-size: 20rpx;
  156. color: #fff;
  157. text-align: center;
  158. white-space: nowrap;
  159. }
  160. }
  161. .wechat-btn {
  162. box-shadow: 0px 0px 20px 4px rgba(199, 199, 199, 0.22);
  163. border-radius: 50%;
  164. width: 80rpx;
  165. height: 80rpx;
  166. .wechat_img {
  167. width: 80rpx;
  168. height: 80rpx;
  169. }
  170. }
  171. }
  172. .img-box {
  173. position: relative;
  174. width: 610rpx;
  175. .modal-img {
  176. width: 100%;
  177. will-change: transform;
  178. height: 830rpx;
  179. }
  180. }
  181. </style>