SharePopup.vue 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. <template>
  2. <div class="share-popup">
  3. <van-popup
  4. v-model="show"
  5. :close-on-click-overlay="false"
  6. >
  7. <div class="share-wrap">
  8. <div class="top-raduis bg-whiter">
  9. <!-- 用户信息 -->
  10. <div class="userinfo-wrap pl-4 pr-4 pt-4 pb-4">
  11. <img class="avatar mr-1" src="~assets/image/activity/invite-user/invite-new-user/avatar.png" alt="">
  12. <div class="userinfo-text ml-1">
  13. <div class="userinfo-name">{{ nickname }}</div>
  14. <div class="userinfo-describe">邀请您使用云手机</div>
  15. </div>
  16. </div>
  17. </div>
  18. <!-- 二维码区域 -->
  19. <div class="qrcode-container bg-whiter pl-6 pr-6 pt-6 pb-6">
  20. <div class="qrcode-img">
  21. <!-- <img class="qrcode" src="~assets/image/activity/invite-user/invite-new-user/qrcode.png" alt=""> -->
  22. <div class="qrcode">
  23. <vue-qr
  24. ref="qrcode"
  25. :text="qrText"
  26. :size="size"
  27. :margin="10"
  28. colorDark="#000"
  29. colorLight="#fff"
  30. :logoSrc="logoSrc"
  31. :logoScale="0.2"
  32. :dotScale="0.7"
  33. />
  34. </div>
  35. </div>
  36. </div>
  37. <div class="arc tips-text bg-whiter">使用微信扫码注册云手机</div>
  38. <div class="btm-raduis bg-whiter pt-6 mb-6"></div>
  39. <div class="share-btn-wrap">
  40. <div class="operate-wrap">
  41. <div class="copy-link" @click="copyCode">复制链接</div>
  42. <div class="save-img" @click="saveImg">保存图片</div>
  43. </div>
  44. <div class="close-wrap mt-5">
  45. <span @click="onClose" class="cancel-btn">取消分享</span>
  46. </div>
  47. </div>
  48. </div>
  49. </van-popup>
  50. </div>
  51. </template>
  52. <script>
  53. import vueQr from 'vue-qr/src/packages/vue-qr.vue';
  54. export default {
  55. name: 'SharePopup',
  56. props: {
  57. nickname: {
  58. type: String,
  59. default: ''
  60. },
  61. qrText: {
  62. type: String,
  63. default: ''
  64. },
  65. logoSrc: {
  66. type: String,
  67. default: ''
  68. },
  69. size: {
  70. type: Number,
  71. default: 190
  72. },
  73. },
  74. components: {
  75. vueQr
  76. },
  77. data() {
  78. return {
  79. show: false,
  80. };
  81. },
  82. methods: {
  83. showPopup() {
  84. this.show = true;
  85. },
  86. onClose() {
  87. this.show = false;
  88. },
  89. async copyCode() {
  90. await this.$native.clipboard.writeText(this.qrText);
  91. this.$toast.success('复制成功');
  92. this.onClose();
  93. },
  94. async saveImg() {
  95. try {
  96. const img = this.$refs.qrcode.$el;
  97. const base64Data = img.src;
  98. // 创建Blob对象
  99. const byteString = atob(base64Data.split(',')[1]);
  100. const mimeString = base64Data.split(',')[0].split(':')[1].split(';')[0];
  101. const ab = new ArrayBuffer(byteString.length);
  102. const ia = new Uint8Array(ab);
  103. for (let i = 0; i < byteString.length; i++) {
  104. ia[i] = byteString.charCodeAt(i);
  105. }
  106. const blob = new Blob([ab], { type: mimeString });
  107. // 创建下载链接
  108. const url = window.URL.createObjectURL(blob);
  109. const a = document.createElement('a');
  110. a.style.display = 'none';
  111. a.href = url;
  112. // 设置下载的文件名
  113. a.download = '1.png';
  114. document.body.appendChild(a);
  115. a.click();
  116. // 清理
  117. window.URL.revokeObjectURL(url);
  118. document.body.removeChild(a);
  119. this.$toast.success('保存成功');
  120. this.onClose();
  121. } catch (error) {
  122. console.log(error)
  123. }
  124. }
  125. },
  126. }
  127. </script>
  128. <style lang="scss" scoped>
  129. .bg-whiter{
  130. background-color: #fff;
  131. }
  132. .share-popup ::v-deep .van-popup {
  133. background-color: transparent;
  134. width: 290px;
  135. }
  136. .top-raduis{
  137. border-top-left-radius: 8px;
  138. border-top-right-radius: 8px;
  139. }
  140. .btm-raduis{
  141. border-bottom-left-radius: 8px;
  142. border-bottom-right-radius: 8px;
  143. }
  144. .arc{
  145. overflow: hidden;
  146. display: flex;
  147. position: relative;
  148. flex-wrap: nowrap;
  149. justify-content: center;
  150. align-items: center;
  151. &::before,&::after{
  152. content: "";
  153. position: absolute;
  154. display: block;
  155. width: 22px;
  156. height: 22px;
  157. background-color: #171611;
  158. border-radius: 50%;
  159. }
  160. &::before{
  161. left: 0;
  162. -webkit-transform: translateX(-50%);
  163. transform: translateX(-50%);
  164. }
  165. &::after{
  166. right: 0;
  167. -webkit-transform: translateX(50%);
  168. transform: translateX(50%);
  169. }
  170. }
  171. .userinfo-wrap{
  172. display: flex;
  173. background-image: url('~/assets/image/activity/invite-user/invite-new-user/share-popup-bg.png');
  174. background-size: 100% 100%;
  175. background-repeat: no-repeat;
  176. background-position: center;
  177. background-origin: padding-box;
  178. .avatar{
  179. flex: 0 0 40px;
  180. width: 40px;
  181. height: 40px;
  182. border-radius: 50%;
  183. background-color: #fff;
  184. }
  185. .userinfo-text{
  186. .userinfo-name{
  187. font-size: 14px;
  188. color: #242424;
  189. }
  190. .userinfo-describe{
  191. color: #979797;
  192. }
  193. }
  194. }
  195. .qrcode-container{
  196. display: flex;
  197. justify-content: center;
  198. align-items: center;
  199. .qrcode-img{
  200. .qrcode{
  201. width: 190px;
  202. height: 190px;
  203. }
  204. }
  205. }
  206. .tips-text{
  207. font-weight: 600;
  208. font-size: 16px;
  209. color: #0A132B;
  210. text-align: center;
  211. }
  212. .share-btn-wrap{
  213. .operate-wrap{
  214. display: flex;
  215. justify-content: space-around;
  216. align-items: center;
  217. .copy-link, .save-img{
  218. width: 113px;
  219. flex: 0 0 113px;
  220. font-weight: 400;
  221. font-size: 16px;
  222. line-height: 36px;
  223. text-align: center;
  224. border-radius: 18px;
  225. position: relative;
  226. }
  227. .copy-link{
  228. color: #0A132B;
  229. background-color: #fff;
  230. &::before{
  231. position: absolute;
  232. top: 50%;
  233. left: 50%;
  234. width: 100%;
  235. height: 100%;
  236. background-color: #000;
  237. border: inherit;
  238. border-color: #000;
  239. border-radius: inherit;
  240. -webkit-transform: translate(-50%, -50%);
  241. transform: translate(-50%, -50%);
  242. opacity: 0;
  243. content: ' ';
  244. }
  245. &:active::before{
  246. opacity: .1;
  247. }
  248. }
  249. .save-img{
  250. background-color: #3370FF;
  251. color: #fff;
  252. &::before{
  253. position: absolute;
  254. top: 50%;
  255. left: 50%;
  256. width: 100%;
  257. height: 100%;
  258. background-color: #000;
  259. border: inherit;
  260. border-color: #000;
  261. border-radius: inherit;
  262. -webkit-transform: translate(-50%, -50%);
  263. transform: translate(-50%, -50%);
  264. opacity: 0;
  265. content: ' ';
  266. }
  267. &:active::before{
  268. opacity: .1;
  269. }
  270. }
  271. }
  272. .close-wrap{
  273. display: flex;
  274. justify-content: center;
  275. align-items: center;
  276. .cancel-btn{
  277. display: inline-block;
  278. font-weight: 400;
  279. font-size: 14px;
  280. color: #FFF;
  281. line-height: 26px;
  282. }
  283. }
  284. }
  285. </style>