Commit 5bca13074e51de1cc5a3289df083f0292f22708d

Authored by 范牧
1 parent fe62536c34
Exists in master

分享功能

... ... @@ -13,6 +13,7 @@ module.exports = {
13 13 "Atomics": "readonly",
14 14 "SharedArrayBuffer": "readonly",
15 15 "uni": true,
  16 + "wx": true,
16 17 "module": true
17 18 },
18 19 "parserOptions": {
... ...
src/components/uni-popup/popup.js
... ... @@ -0,0 +1,25 @@
  1 +// import message from './message.js'
  2 +// 定义 type 类型:弹出类型:top/bottom/center
  3 +const config = {
  4 + // 顶部弹出
  5 + top: 'top',
  6 + // 底部弹出
  7 + bottom: 'bottom',
  8 + // 居中弹出
  9 + center: 'center',
  10 + // 消息提示
  11 + message: 'top',
  12 + // 对话框
  13 + dialog: 'center',
  14 + // 分享
  15 + share: 'bottom',
  16 +}
  17 +
  18 +export default {
  19 + data() {
  20 + return {
  21 + config: config,
  22 + }
  23 + },
  24 + // mixins: [message],
  25 +}
... ...
src/components/uni-popup/uni-popup-post.vue
... ... @@ -0,0 +1,207 @@
  1 +<template>
  2 + <view class="uni-popup-post">
  3 + <image
  4 + class="uni_post_img"
  5 + :src="postUrl"
  6 + />
  7 + <view
  8 + @tap="saveAndClose"
  9 + class="uni_post_button_box"
  10 + >
  11 + 保存图片
  12 + </view>
  13 + </view>
  14 +</template>
  15 +
  16 +<script>
  17 +export default {
  18 + name: 'UniPopupPost',
  19 + props: {
  20 + postUrl: {
  21 + type: String,
  22 + default: 'https://api.glass.xiuyetang.com/adv_pic/428_0_7.png',
  23 + },
  24 + },
  25 + inject: ['popup'],
  26 + data() {
  27 + return {}
  28 + },
  29 + created() {
  30 + console.log('dada', this)
  31 + },
  32 + methods: {
  33 + // 保存图片并关闭窗口
  34 + saveAndClose() {
  35 + // 获取用户保存相册权限
  36 + const scope = 'scope.writePhotosAlbum'
  37 + const that = this
  38 + uni.getSetting({
  39 + success(res) {
  40 + console.log('获取用户保存相册权限', res)
  41 + if (!res.authSetting[scope]) {
  42 + uni.authorize({
  43 + scope,
  44 + success() {
  45 + console.log('获取用户保存相册权限---->', '授权成功')
  46 + // 保存到相册
  47 + uni.showLoading({
  48 + title: '保存中',
  49 + })
  50 + that.saveImage()
  51 + },
  52 + fail() {
  53 + console.log('获取用户保存相册权限---->', '授权失败')
  54 + that.secondGetPhoteAuthor()
  55 + },
  56 + })
  57 + } else {
  58 + console.log('拥有授权权限')
  59 + // 保存到相册
  60 + uni.showLoading({
  61 + title: '保存中',
  62 + })
  63 + that.saveImage()
  64 + }
  65 +
  66 + that.popup.close()
  67 + },
  68 + fail(res) {
  69 + console.log('授权失败------>', res)
  70 + uni.showToast({
  71 + title: '保存失败',
  72 + icon: 'none',
  73 + duration: 2000,
  74 + })
  75 + },
  76 + })
  77 + },
  78 + // 保存到相册
  79 + saveImage() {
  80 + const that = this
  81 + uni.getImageInfo({
  82 + src: that.postUrl,
  83 + success(res) {
  84 + console.log('图片读取是否可行', res)
  85 + uni.saveImageToPhotosAlbum({
  86 + filePath: res.path,
  87 + success() {
  88 + uni.showToast({
  89 + title: '已保存到相册',
  90 + icon: 'none',
  91 + duration: 2000,
  92 + })
  93 + uni.hideLoading()
  94 + },
  95 + fail(err) {
  96 + console.log('用户拒绝', err)
  97 + if (err.errMsg === 'saveImageToPhotosAlbum:fail auth deny') {
  98 + console.log('当用户拒绝,再次发起授权')
  99 + that.secondGetPhoteAuthor()
  100 + } else if (err.errMsg === 'saveImageToPhotosAlbum:fail cancel') {
  101 + uni.showToast({
  102 + title: '已取消保存',
  103 + icon: 'none',
  104 + duration: 2000,
  105 + })
  106 + uni.hideLoading()
  107 + } else {
  108 + uni.showToast({
  109 + title: '请截屏保存分享',
  110 + icon: 'none',
  111 + duration: 2000,
  112 + })
  113 + uni.hideLoading()
  114 + }
  115 + },
  116 + })
  117 + },
  118 + fail(res) {
  119 + console.log('授权失败----->', res)
  120 + uni.hideLoading()
  121 + uni.showToast({
  122 + title: '保存失败',
  123 + icon: 'none',
  124 + duration: 2000,
  125 + })
  126 + },
  127 + })
  128 + },
  129 + // 二次请求授权
  130 + secondGetPhoteAuthor() {
  131 + const that = this
  132 + uni.showModal({
  133 + title: '保存海报',
  134 + content: '需要您提供保存相册权限',
  135 + success: (res) => {
  136 + if (res.confirm) {
  137 + uni.openSetting({
  138 + success(settingdata) {
  139 + console.log('settingdata 二次弹窗获取', settingdata)
  140 + if (settingdata.authSetting['scope.writePhotosAlbum']) {
  141 + console.log('二次弹窗获取---->', '获取 相册 权限成功,给出再次点击图片保存到相册的提示。')
  142 + uni.showLoading({
  143 + title: '保存中',
  144 + })
  145 + that.saveImage()
  146 + } else {
  147 + uni.showToast({
  148 + title: '保存失败',
  149 + icon: 'none',
  150 + duration: 2000,
  151 + })
  152 + console.log('二次弹窗获取', '获取 相册 权限失败,给出不给权限就无法正常使用的提示')
  153 + }
  154 + },
  155 + })
  156 + } else {
  157 + uni.showToast({
  158 + title: '保存失败',
  159 + icon: 'none',
  160 + duration: 2000,
  161 + })
  162 + }
  163 + },
  164 + fail(err) {
  165 + uni.showToast({
  166 + title: '保存失败',
  167 + icon: 'none',
  168 + duration: 2000,
  169 + })
  170 + console.log('再次失败', err)
  171 + },
  172 + })
  173 + },
  174 + },
  175 +}
  176 +</script>
  177 +<style lang="scss" scoped>
  178 +.uni-popup-post {
  179 + border-radius: 8px 8px 0px 0px;
  180 + display: flex;
  181 + flex-direction: column;
  182 + justify-content: space-between;
  183 + align-items: center;
  184 +}
  185 +
  186 +.uni_post_img {
  187 + width: 690rpx;
  188 + height: 466.667px;
  189 + margin-top: -180rpx;
  190 +}
  191 +
  192 +.uni_post_button_box {
  193 + height: 112rpx;
  194 + line-height: 112rpx;
  195 + background-color: #ff6b4a;
  196 + border-radius: 4px;
  197 + width: 350px;
  198 + color: #fff;
  199 + text-align: center;
  200 + margin-top: 44rpx;
  201 + font-family: PingFangSC-Medium;
  202 + font-size: 14px;
  203 + color: #ffffff;
  204 + letter-spacing: -0.26px;
  205 + text-align: center;
  206 +}
  207 +</style>
... ...
src/components/uni-popup/uni-popup-share.vue
... ... @@ -0,0 +1,185 @@
  1 +<template>
  2 + <view class="uni-popup-share">
  3 + <!-- <view class="uni-share-title"><text class="uni-share-title-text">{{title}}</text></view> -->
  4 + <view class="uni-share-content">
  5 + <view class="uni-share-content-box">
  6 + <button
  7 + class="uni-share-content-item"
  8 + v-for="(item,index) in bottomData"
  9 + :key="index"
  10 + :open-type="item.name === 'friend' ? 'share': ''"
  11 + @click.stop="select(item,index)"
  12 + >
  13 + <image
  14 + class="uni-share-image"
  15 + :src="item.icon"
  16 + mode="aspectFill"
  17 + ></image>
  18 + <view class="uni-share-text">{{item.text}}</view>
  19 + </button>
  20 + </view>
  21 + </view>
  22 + <view
  23 + @tap="close"
  24 + class="uni-share-button-box"
  25 + >
  26 + 取消
  27 + </view>
  28 + </view>
  29 +</template>
  30 +
  31 +<script>
  32 +export default {
  33 + name: 'UniPopupShare',
  34 + props: {
  35 + title: {
  36 + type: String,
  37 + default: '分享到',
  38 + },
  39 + },
  40 + inject: ['popup'],
  41 + data() {
  42 + return {
  43 + bottomData: [{
  44 + text: '推荐到好物圈',
  45 + icon: '/static/img/share/recommend.png',
  46 + name: 'recommend',
  47 + }, {
  48 + text: '转发给朋友/群',
  49 + icon: '/static/img/share/friend.png',
  50 + name: 'friend',
  51 + }, {
  52 + text: '生成海报',
  53 + icon: '/static/img/share/poster.png',
  54 + name: 'poster',
  55 + },
  56 + ],
  57 + }
  58 + },
  59 + created() {},
  60 + methods: {
  61 + /**
  62 + * 选择内容
  63 + */
  64 + select(item, index) {
  65 + this.$emit('select', {
  66 + item,
  67 + index,
  68 + }, () => {
  69 + this.popup.close()
  70 + })
  71 + },
  72 + /**
  73 + * 关闭窗口
  74 + */
  75 + close() {
  76 + this.popup.close()
  77 + },
  78 + },
  79 +}
  80 +</script>
  81 +<style lang="scss" scoped>
  82 +.uni-popup-share {
  83 + background-color: #fff;
  84 + border-radius: 8px 8px 0px 0px;
  85 +}
  86 +.uni-share-title {
  87 + /* #ifndef APP-NVUE */
  88 + display: flex;
  89 + /* #endif */
  90 + flex-direction: row;
  91 + align-items: center;
  92 + justify-content: center;
  93 + height: 40px;
  94 +}
  95 +.uni-share-title-text {
  96 + font-size: 14px;
  97 + color: #666;
  98 +}
  99 +.uni-share-content {
  100 + /* #ifndef APP-NVUE */
  101 + display: flex;
  102 + /* #endif */
  103 + flex-direction: row;
  104 + justify-content: center;
  105 + padding-top: 10px;
  106 +}
  107 +
  108 +.uni-share-content-box {
  109 + /* #ifndef APP-NVUE */
  110 + display: flex;
  111 + /* #endif */
  112 +
  113 + flex-direction: column;
  114 + justify-content: space-between;
  115 + width: 360px;
  116 +}
  117 +
  118 +.uni-share-content-item {
  119 + /* #ifndef APP-NVUE */
  120 + display: flex;
  121 + /* #endif */
  122 + flex-direction: row;
  123 + flex-wrap: wrap;
  124 + padding: 10px 0;
  125 + align-items: center;
  126 + border-bottom: 1px solid #f2f2f2;
  127 +
  128 + background-color: #fff;
  129 + font-family: PingFangSC-Regular;
  130 + font-size: 16px;
  131 + color: #333333;
  132 + letter-spacing: -0.3px;
  133 + margin: 0;
  134 + &::after {
  135 + border: 0;
  136 + }
  137 +}
  138 +
  139 +.uni-share-content-item:active {
  140 + background-color: #f5f5f5;
  141 +}
  142 +
  143 +.uni-share-image {
  144 + width: 84rpx;
  145 + height: 84rpx;
  146 + vertical-align: middle;
  147 + margin-left: 40rpx;
  148 +}
  149 +
  150 +.uni-share-text {
  151 + font-family: PingFangSC-Regular;
  152 + font-size: 16px;
  153 + color: #3b4144;
  154 + margin-left: 20rpx;
  155 +}
  156 +// .share_button {
  157 +// border: none;
  158 +// }
  159 +
  160 +.uni-share-button-box {
  161 + /* #ifndef APP-NVUE */
  162 + // display: flex;
  163 + /* #endif */
  164 + // flex-direction: row;
  165 + // padding: 10px 15px;
  166 + height: 100rpx;
  167 + font-family: PingFangSC-Regular;
  168 + font-size: 16px;
  169 + color: #333333;
  170 + letter-spacing: -0.3px;
  171 + text-align: center;
  172 + line-height: 100rpx;
  173 +}
  174 +
  175 +.uni-share-button {
  176 + flex: 1;
  177 + border-radius: 50px;
  178 + color: #666;
  179 + font-size: 16px;
  180 +}
  181 +
  182 +.uni-share-button::after {
  183 + border-radius: 50px;
  184 +}
  185 +</style>
... ...
src/components/uni-popup/uni-popup.vue
... ... @@ -0,0 +1,313 @@
  1 +<template>
  2 + <view
  3 + v-if="showPopup"
  4 + class="uni-popup"
  5 + :class="[popupstyle]"
  6 + @touchmove.stop.prevent="clear"
  7 + >
  8 + <uni-transition
  9 + v-if="maskShow"
  10 + :mode-class="['fade']"
  11 + :styles="maskClass"
  12 + :duration="duration"
  13 + :show="showTrans"
  14 + @click="onTap"
  15 + />
  16 + <uni-transition
  17 + :mode-class="ani"
  18 + :styles="transClass"
  19 + :duration="duration"
  20 + :show="showTrans"
  21 + @click="onTap"
  22 + >
  23 + <view
  24 + class="uni-popup__wrapper-box"
  25 + @click.stop="clear"
  26 + >
  27 + <slot />
  28 + </view>
  29 + </uni-transition>
  30 + </view>
  31 +</template>
  32 +
  33 +<script>
  34 +import uniTransition from '../uni-transition/uni-transition.vue'
  35 +import popup from './popup.js'
  36 +/**
  37 + * PopUp 弹出层
  38 + * @description 弹出层组件,为了解决遮罩弹层的问题
  39 + * @tutorial https://ext.dcloud.net.cn/plugin?id=329
  40 + * @property {String} type = [top|center|bottom] 弹出方式
  41 + * @value top 顶部弹出
  42 + * @value center 中间弹出
  43 + * @value bottom 底部弹出
  44 + * @value message 消息提示
  45 + * @value dialog 对话框
  46 + * @value share 底部分享示例
  47 + * @property {Boolean} animation = [ture|false] 是否开启动画
  48 + * @property {Boolean} maskClick = [ture|false] 蒙版点击是否关闭弹窗
  49 + * @event {Function} change 打开关闭弹窗触发,e={show: false}
  50 + */
  51 +
  52 +export default {
  53 + name: 'UniPopup',
  54 + components: {
  55 + uniTransition,
  56 + },
  57 + props: {
  58 + // 开启动画
  59 + animation: {
  60 + type: Boolean,
  61 + default: true,
  62 + },
  63 + // 弹出层类型,可选值,top: 顶部弹出层;bottom:底部弹出层;center:全屏弹出层
  64 + // message: 消息提示 ; dialog : 对话框
  65 + type: {
  66 + type: String,
  67 + default: 'center',
  68 + },
  69 + // maskClick
  70 + maskClick: {
  71 + type: Boolean,
  72 + default: true,
  73 + },
  74 + },
  75 + provide() {
  76 + return {
  77 + popup: this,
  78 + }
  79 + },
  80 + mixins: [popup],
  81 + watch: {
  82 + /**
  83 + * 监听type类型
  84 + */
  85 + type: {
  86 + handler: function(newVal) {
  87 + this[this.config[newVal]]()
  88 + },
  89 + immediate: true,
  90 + },
  91 + /**
  92 + * 监听遮罩是否可点击
  93 + * @param {Object} val
  94 + */
  95 + maskClick(val) {
  96 + this.mkclick = val
  97 + },
  98 + },
  99 + data() {
  100 + return {
  101 + duration: 300,
  102 + ani: [],
  103 + showPopup: false,
  104 + showTrans: false,
  105 + maskClass: {
  106 + position: 'fixed',
  107 + bottom: 0,
  108 + top: 0,
  109 + left: 0,
  110 + right: 0,
  111 + backgroundColor: 'rgba(0, 0, 0, 0.4)',
  112 + },
  113 + transClass: {
  114 + position: 'fixed',
  115 + left: 0,
  116 + right: 0,
  117 + },
  118 + maskShow: true,
  119 + mkclick: true,
  120 + popupstyle: 'top',
  121 + }
  122 + },
  123 + created() {
  124 + this.mkclick = this.maskClick
  125 + if (this.animation) {
  126 + this.duration = 300
  127 + } else {
  128 + this.duration = 0
  129 + }
  130 + },
  131 + methods: {
  132 + clear(e) {
  133 + // TODO nvue 取消冒泡
  134 + e.stopPropagation()
  135 + },
  136 + open() {
  137 + this.showPopup = true
  138 + this.$nextTick(() => {
  139 + new Promise(resolve => {
  140 + clearTimeout(this.timer)
  141 + this.timer = setTimeout(() => {
  142 + this.showTrans = true
  143 + // fixed by mehaotian 兼容 app 端
  144 + this.$nextTick(() => {
  145 + resolve()
  146 + })
  147 + }, 50)
  148 + }).then(res => {
  149 + // 自定义打开事件
  150 + clearTimeout(this.msgtimer)
  151 + this.msgtimer = setTimeout(() => {
  152 + this.customOpen && this.customOpen()
  153 + }, 100)
  154 + this.$emit('change', {
  155 + show: true,
  156 + type: this.type,
  157 + })
  158 + })
  159 + })
  160 + },
  161 + close(type) {
  162 + this.showTrans = false
  163 + this.$nextTick(() => {
  164 + this.$emit('change', {
  165 + show: false,
  166 + type: this.type,
  167 + })
  168 + clearTimeout(this.timer)
  169 + // 自定义关闭事件
  170 + this.customOpen && this.customClose()
  171 + this.timer = setTimeout(() => {
  172 + this.showPopup = false
  173 + }, 300)
  174 + })
  175 + },
  176 + onTap() {
  177 + if (!this.mkclick) return
  178 + this.close()
  179 + },
  180 + /**
  181 + * 顶部弹出样式处理
  182 + */
  183 + top() {
  184 + this.popupstyle = 'top'
  185 + this.ani = ['slide-top']
  186 + this.transClass = {
  187 + position: 'fixed',
  188 + left: 0,
  189 + right: 0,
  190 + }
  191 + },
  192 + /**
  193 + * 底部弹出样式处理
  194 + */
  195 + bottom() {
  196 + this.popupstyle = 'bottom'
  197 + this.ani = ['slide-bottom']
  198 + this.transClass = {
  199 + position: 'fixed',
  200 + left: 0,
  201 + right: 0,
  202 + bottom: 0,
  203 + }
  204 + },
  205 + /**
  206 + * 中间弹出样式处理
  207 + */
  208 + center() {
  209 + this.popupstyle = 'center'
  210 + this.ani = ['zoom-out', 'fade']
  211 + this.transClass = {
  212 + position: 'fixed',
  213 + /* #ifndef APP-NVUE */
  214 + display: 'flex',
  215 + flexDirection: 'column',
  216 + /* #endif */
  217 + bottom: 0,
  218 + left: 0,
  219 + right: 0,
  220 + top: 0,
  221 + justifyContent: 'center',
  222 + alignItems: 'center',
  223 + }
  224 + },
  225 + },
  226 +}
  227 +</script>
  228 +<style lang="scss" scoped>
  229 +.uni-popup {
  230 + position: fixed;
  231 + /* #ifndef APP-NVUE */
  232 + z-index: 99;
  233 + /* #endif */
  234 +}
  235 +
  236 +.uni-popup__mask {
  237 + position: absolute;
  238 + top: 0;
  239 + bottom: 0;
  240 + left: 0;
  241 + right: 0;
  242 + background-color: $uni-bg-color-mask;
  243 + opacity: 0;
  244 +}
  245 +
  246 +.mask-ani {
  247 + transition-property: opacity;
  248 + transition-duration: 0.2s;
  249 +}
  250 +
  251 +.uni-top-mask {
  252 + opacity: 1;
  253 +}
  254 +
  255 +.uni-bottom-mask {
  256 + opacity: 1;
  257 +}
  258 +
  259 +.uni-center-mask {
  260 + opacity: 1;
  261 +}
  262 +
  263 +.uni-popup__wrapper {
  264 + /* #ifndef APP-NVUE */
  265 + display: block;
  266 + /* #endif */
  267 + position: absolute;
  268 +}
  269 +
  270 +.top {
  271 + /* #ifdef H5 */
  272 + top: var(--window-top);
  273 + /* #endif */
  274 + /* #ifndef H5 */
  275 + top: 0;
  276 + /* #endif */
  277 +}
  278 +
  279 +.bottom {
  280 + bottom: 0;
  281 +}
  282 +
  283 +.uni-popup__wrapper-box {
  284 + /* #ifndef APP-NVUE */
  285 + display: block;
  286 + /* #endif */
  287 + position: relative;
  288 + /* iphonex 等安全区设置,底部安全区适配 */
  289 + /* #ifndef APP-NVUE */
  290 + padding-bottom: constant(safe-area-inset-bottom);
  291 + padding-bottom: env(safe-area-inset-bottom);
  292 + /* #endif */
  293 +}
  294 +
  295 +.content-ani {
  296 + // transition: transform 0.3s;
  297 + transition-property: transform, opacity;
  298 + transition-duration: 0.2s;
  299 +}
  300 +
  301 +.uni-top-content {
  302 + transform: translateY(0);
  303 +}
  304 +
  305 +.uni-bottom-content {
  306 + transform: translateY(0);
  307 +}
  308 +
  309 +.uni-center-content {
  310 + transform: scale(1);
  311 + opacity: 1;
  312 +}
  313 +</style>
... ...
src/pages/details/components/Introduce.vue
... ... @@ -120,12 +120,8 @@ export default {
120 120 tag: Object,
121 121 },
122 122 created() {
123   - console.log('lalal')
124   - console.log('tag', this)
125 123 },
126 124 updated() {
127   - console.log('lalal-2')
128   - console.log('tag-2', this.tag)
129 125 },
130 126 }
131 127 </script>
... ...
src/pages/details/details.vue
... ... @@ -31,7 +31,10 @@
31 31 <!-- 产品名称 -->
32 32 <view class="info_name">
33 33 <text class="info_name_name">{{goodsInfo.name || '暂无'}}</text>
34   - <view class="info_name_share">
  34 + <view
  35 + @tap="confirmShare"
  36 + class="info_name_share"
  37 + >
35 38 <image src="/static/img/detail/share-icon.png"></image>
36 39 <text>分享</text>
37 40 </view>
... ... @@ -164,19 +167,51 @@
164 167 >立即购买</view>
165 168 </view>
166 169 </view>
  170 + <!-- 参数选择 -->
  171 + <!-- <BottomSheet
  172 + :isCart="isCart"
  173 + @addCart="addCart"
  174 + :pid="pid"
  175 + :goodInfo="goodInfo"
  176 + :isShowBottom="isShowBottom"
  177 + @closeBottom="closeBottom"
  178 + ></BottomSheet> -->
  179 + <!-- 分享 -->
  180 + <template>
  181 + <uni-popup
  182 + ref="popupShare"
  183 + type="share"
  184 + >
  185 + <uni-popup-share @select="selectShare"></uni-popup-share>
  186 + </uni-popup>
  187 + </template>
  188 + <!-- 分享海报 -->
  189 + <template>
  190 + <uni-popup
  191 + ref="uniPopupPost"
  192 + type="center"
  193 + >
  194 + <uni-popup-post :postUrl="postUrl"></uni-popup-post>
  195 + </uni-popup>
  196 + </template>
167 197 </view>
168 198 </template>
169 199  
170 200 <script>
171 201 import store from '@/store'
172   -import Introduce from './components/Introduce' // 商品介绍基本信息
  202 +import Introduce from './components/Introduce' // 商品介绍基本信息组件
173 203 import AfterSails from './components/AfterSails' // 售后保障组件
174   -// import BottomSheet from '@/components/BottomSheet.vue'
  204 +import uniPopupShare from '@/components/uni-popup/uni-popup-share.vue' // 分享组件
  205 +import uniPopupPost from '@/components/uni-popup/uni-popup-post.vue' // 分享组件
  206 +// import BottomSheet from '@/components/BottomSheet/BottomSheet.vue' // 参数选择组件
175 207  
176 208 export default {
177 209 components: {
178 210 Introduce,
179 211 AfterSails,
  212 + // BottomSheet,
  213 + uniPopupShare,
  214 + uniPopupPost,
180 215 },
181 216 data () {
182 217 return {
... ... @@ -189,6 +224,7 @@ export default {
189 224 '规格参数',
190 225 '售后保障',
191 226 ],
  227 + showPostImg: false, // 是否展示分享海报
192 228 }
193 229 },
194 230 onLoad({ pid = this.pid, sk_id: skId }) {
... ... @@ -230,6 +266,14 @@ export default {
230 266 cartNumber() {
231 267 return this.$store.state.details.cartNumber
232 268 },
  269 + // 购物车数目
  270 + skuList() {
  271 + return this.$store.state.details.skuList
  272 + },
  273 + // 分享海报
  274 + postUrl() {
  275 + return this.$store.state.details.postUrl
  276 + },
233 277 },
234 278 methods: {
235 279 // 获取产品详情
... ... @@ -249,6 +293,103 @@ export default {
249 293 this.item_current = e
250 294 }
251 295 },
  296 + // 打开分享界面
  297 + confirmShare() {
  298 + this.$refs.popupShare.open()
  299 + },
  300 + // 选择分享
  301 + selectShare(e, done) {
  302 + switch (e.item.name) {
  303 + // 分享到好物圈
  304 + case 'recommend':
  305 + this.shareRecommend()
  306 + break
  307 + // 分享到朋友圈
  308 + case 'friend':
  309 + break
  310 + // 生成海报
  311 + case 'poster':
  312 + uni.showLoading({
  313 + title: '生成图片中',
  314 + })
  315 + this.sharePost()
  316 + break
  317 + default:
  318 + break
  319 + }
  320 + done()
  321 + },
  322 + // 分享到好物圈
  323 + shareRecommend() {
  324 + if (wx.openBusinessView) {
  325 + wx.openBusinessView({
  326 + businessType: 'friendGoodsRecommend',
  327 + extraData: {
  328 + product: {
  329 + item_code: '58_68',
  330 + title: this.goodsInfo.name,
  331 + image_list: this.carousel,
  332 + },
  333 + },
  334 + success: function (res) {
  335 + uni.showToast({
  336 + title: '好物圈分享成功!',
  337 + icon: 'none',
  338 + duration: 2000,
  339 + })
  340 + // 向服务器报告这个事情
  341 + // TODO:::记录这个用户的推广过程。
  342 + console.log('好物圈分享成功!', res)
  343 + },
  344 + fail: function (res) {
  345 + console.log('好物圈分享失败!', res)
  346 + },
  347 + })
  348 + }
  349 + },
  350 + // 分享到朋友/圈
  351 + shareFriend() {
  352 + this.onShareAppMessage()
  353 + },
  354 + // 朋友圈设置页面
  355 + onShareAppMessage() {
  356 + let myName = this.$store.state.user.userInfo.nickName
  357 + if (myName === '' || myName.length < 1 || myName === '匿名用户' || typeof myName === 'undefined') {
  358 + myName = '【神秘人】'
  359 + } else {
  360 + myName = '【' + myName + '】'
  361 + }
  362 + const uid = uni.getStorageSync('uid')
  363 + return {
  364 + title: 'Hi,' + myName + '送你300元来试戴最新潮流眼镜!', // 默认是小程序的名称(可以写slogan等)
  365 + path: '/pages/index/detail/index?uid=' + uid + '&sid=0&pid=' + this.pid,
  366 + imageUrl: this.skuList[0].pic, // 不传入 imageUrl 则使用默认截图。显示图片长宽比是 5:4
  367 + success: function (res) {
  368 + if (res.errMsg === 'shareAppMessage:ok') {
  369 + console.log('分享成功!', res)
  370 + }
  371 + },
  372 + fail: function (res) {
  373 + if (res.errMsg === 'shareAppMessage:fail cancel') {
  374 + console.log('fail', '放弃分享')
  375 + } else if (res.errMsg === 'shareAppMessage:fail') {
  376 + console.log('fail', '分享失败')
  377 + }
  378 + },
  379 + }
  380 + },
  381 + // 生成海报
  382 + sharePost() {
  383 + const fromsid = this.$store.state.user.fromInfo.fromsid || 'undefined'
  384 +
  385 + store.dispatch('details/post', {
  386 + pid: this.pid,
  387 + sid: fromsid === 'undefined' ? 0 : fromsid,
  388 + }).then((data) => {
  389 + uni.hideLoading()
  390 + this.$refs.uniPopupPost.open()
  391 + })
  392 + },
252 393 },
253 394 }
254 395 </script>
... ... @@ -293,6 +434,7 @@ export default {
293 434 .info_pay_number {
294 435 color: #999;
295 436 font-size: 14px;
  437 + font-family: PingFangSC-Regular;
296 438 }
297 439 }
298 440 // 产品名称
... ... @@ -459,6 +601,10 @@ export default {
459 601 justify-content: space-between;
460 602 align-content: center;
461 603 margin: 0;
  604 + /* iphonex 等安全区设置,底部安全区适配 */
  605 + /* #ifndef APP-NVUE */
  606 + padding-bottom: constant(safe-area-inset-bottom);
  607 + padding-bottom: env(safe-area-inset-bottom);
462 608 .menu_1 {
463 609 width: 20%;
464 610 height: 100%;
... ...
src/static/img/share/friend.png

6.4 KB

src/static/img/share/poster.png

6.92 KB

src/static/img/share/recommend.png

7.38 KB

src/store/modules/details.js
... ... @@ -4,6 +4,7 @@ import request from &#39;../request&#39;
4 4 const {
5 5 read,
6 6 cartList,
  7 + makePost,
7 8 } = urlAlias
8 9  
9 10 const state = {
... ... @@ -44,20 +45,27 @@ const state = {
44 45 more: '',
45 46 // 购物车数目
46 47 cartNumber: 0,
  48 + // skuList
  49 + skuList: [],
  50 + postUrl: 'https://api.glass.xiuyetang.com/adv_pic/428_0_7.png',
47 51 }
48 52  
49 53 const mutations = {
50   - INIT: (state, { carousel, goodsInfo, tag, specification, evaluate, more }) => {
  54 + INIT: (state, { carousel, goodsInfo, tag, specification, evaluate, more, skuList }) => {
51 55 state.carousel = carousel
52 56 state.goodsInfo = goodsInfo
53 57 state.tag = tag
54 58 state.specification = specification
55 59 state.evaluate = evaluate
56 60 state.more = more
  61 + state.skuList = skuList
57 62 },
58 63 CART: (state, number) => {
59 64 state.cartNumber = number
60 65 },
  66 + POST: (state, url) => {
  67 + state.postUrl = url
  68 + },
61 69 }
62 70  
63 71 const actions = {
... ... @@ -87,6 +95,7 @@ const actions = {
87 95 }
88 96  
89 97 commit('INIT', {
  98 + skuList: data.skuList,
90 99 carousel: data.pics,
91 100 goodsInfo: {
92 101 name: data.p_name,
... ... @@ -101,6 +110,7 @@ const actions = {
101 110 tag: data.judge_tag,
102 111 star: parseInt(5 * Number(data.judgeInfo.good.slice(0, -1)) / 100),
103 112 },
  113 + // eslint-disable-next-line
104 114 more: data.prodIntro1.replace(/\<img/gi, '<img style="max-width:100%;height:auto"'),
105 115 })
106 116 resolve(data)
... ... @@ -116,7 +126,6 @@ const actions = {
116 126 url: cartList,
117 127 data: param,
118 128 success: ({ data: { data } }) => {
119   - console.log('cartData', data)
120 129 let number = 0
121 130 for (let index = 0; index < data.length; index++) {
122 131 number += Number(data[index].num)
... ... @@ -125,6 +134,17 @@ const actions = {
125 134 },
126 135 }))
127 136 },
  137 + // 生成分享海报
  138 + post({ commit }, param) {
  139 + return new Promise((resolve) => request({
  140 + url: makePost,
  141 + data: param,
  142 + success: ({ data }) => {
  143 + commit('POST', data.data)
  144 + resolve()
  145 + },
  146 + }))
  147 + },
128 148 }
129 149  
130 150 export default {
... ...
... ... @@ -35,6 +35,7 @@ const urlAlias = {
35 35 detailStandardList: '/app/prod/read', // 获取商品的详细信息
36 36 // 选购页
37 37 detailStandardUrl: '/app/prod/read', // 获取商品的详细信息
  38 + makePost: '/app/glass/makeProdAdvPic', // 生成分享海报
38 39  
39 40 // 地址管理
40 41 editAddress: '/app/address/edit_address', // 编辑地址
... ...