Commit 5bca13074e51de1cc5a3289df083f0292f22708d
1 parent
fe62536c34
Exists in
master
分享功能
Showing
12 changed files
with
903 additions
and
9 deletions
Show diff stats
.eslintrc.js
1 | module.exports = { | 1 | module.exports = { |
2 | "env": { | 2 | "env": { |
3 | "browser": true, | 3 | "browser": true, |
4 | "es6": true | 4 | "es6": true |
5 | }, | 5 | }, |
6 | "extends": [ | 6 | "extends": [ |
7 | 'standard', | 7 | 'standard', |
8 | "eslint:recommended", | 8 | "eslint:recommended", |
9 | "plugin:vue/essential", | 9 | "plugin:vue/essential", |
10 | "plugin:@typescript-eslint/eslint-recommended", | 10 | "plugin:@typescript-eslint/eslint-recommended", |
11 | ], | 11 | ], |
12 | "globals": { | 12 | "globals": { |
13 | "Atomics": "readonly", | 13 | "Atomics": "readonly", |
14 | "SharedArrayBuffer": "readonly", | 14 | "SharedArrayBuffer": "readonly", |
15 | "uni": true, | 15 | "uni": true, |
16 | "wx": true, | ||
16 | "module": true | 17 | "module": true |
17 | }, | 18 | }, |
18 | "parserOptions": { | 19 | "parserOptions": { |
19 | "ecmaVersion": 11, | 20 | "ecmaVersion": 11, |
20 | "parser": "@typescript-eslint/parser", | 21 | "parser": "@typescript-eslint/parser", |
21 | "sourceType": "module" | 22 | "sourceType": "module" |
22 | }, | 23 | }, |
23 | "plugins": [ | 24 | "plugins": [ |
24 | "vue", | 25 | "vue", |
25 | "@typescript-eslint" | 26 | "@typescript-eslint" |
26 | ], | 27 | ], |
27 | "rules": { | 28 | "rules": { |
28 | quotes: ['error', 'single'], | 29 | quotes: ['error', 'single'], |
29 | 'space-before-function-paren': 0, | 30 | 'space-before-function-paren': 0, |
30 | // 数组和对象键值对最后一个逗号, never参数:不能带末尾的逗号, always参数:必须带末尾的逗号, | 31 | // 数组和对象键值对最后一个逗号, never参数:不能带末尾的逗号, always参数:必须带末尾的逗号, |
31 | // always-multiline:多行模式必须带逗号,单行模式不能带逗号 | 32 | // always-multiline:多行模式必须带逗号,单行模式不能带逗号 |
32 | "comma-dangle": [2, "always-multiline"], | 33 | "comma-dangle": [2, "always-multiline"], |
33 | // 控制逗号前后的空格 | 34 | // 控制逗号前后的空格 |
34 | "comma-spacing": [2, { "before": false, "after": true }], | 35 | "comma-spacing": [2, { "before": false, "after": true }], |
35 | // 控制逗号在行尾出现还是在行首出现 | 36 | // 控制逗号在行尾出现还是在行首出现 |
36 | // http://eslint.org/docs/rules/comma-style | 37 | // http://eslint.org/docs/rules/comma-style |
37 | "comma-style": [2, "last"], | 38 | "comma-style": [2, "last"], |
38 | } | 39 | } |
39 | }; | 40 | }; |
40 | 41 |
src/components/uni-popup/popup.js
File was created | 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 | } | ||
26 |
src/components/uni-popup/uni-popup-post.vue
File was created | 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> | ||
208 |
src/components/uni-popup/uni-popup-share.vue
File was created | 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> | ||
186 |
src/components/uni-popup/uni-popup.vue
File was created | 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> | ||
314 |
src/pages/details/components/Introduce.vue
1 | <template> | 1 | <template> |
2 | <view class="introduce"> | 2 | <view class="introduce"> |
3 | <!-- 迭代时建议配合接口修改 为数组 --> | 3 | <!-- 迭代时建议配合接口修改 为数组 --> |
4 | <view v-if="tag.prod_tag_age && tag.prod_tag_age.length !== 0"> | 4 | <view v-if="tag.prod_tag_age && tag.prod_tag_age.length !== 0"> |
5 | <view> | 5 | <view> |
6 | 年龄:<view | 6 | 年龄:<view |
7 | v-for="(item,index) in tag.prod_tag_age" | 7 | v-for="(item,index) in tag.prod_tag_age" |
8 | :key="index" | 8 | :key="index" |
9 | > | 9 | > |
10 | {{item.label}}<text v-if="index !== tag.prod_tag_age.length - 1">/</text> | 10 | {{item.label}}<text v-if="index !== tag.prod_tag_age.length - 1">/</text> |
11 | </view> | 11 | </view> |
12 | </view> | 12 | </view> |
13 | </view> | 13 | </view> |
14 | <view v-if="tag.prod_tag_color && tag.prod_tag_color.length !== 0"> | 14 | <view v-if="tag.prod_tag_color && tag.prod_tag_color.length !== 0"> |
15 | <view> | 15 | <view> |
16 | 颜色:<view | 16 | 颜色:<view |
17 | v-for="(item,index) in tag.prod_tag_color" | 17 | v-for="(item,index) in tag.prod_tag_color" |
18 | :key="index" | 18 | :key="index" |
19 | > | 19 | > |
20 | {{item.label}}<text v-if="index !== tag.prod_tag_color.length - 1">/</text> | 20 | {{item.label}}<text v-if="index !== tag.prod_tag_color.length - 1">/</text> |
21 | </view> | 21 | </view> |
22 | </view> | 22 | </view> |
23 | </view> | 23 | </view> |
24 | <view v-if="tag.prod_tag_face && tag.prod_tag_face.length !== 0"> | 24 | <view v-if="tag.prod_tag_face && tag.prod_tag_face.length !== 0"> |
25 | <view> | 25 | <view> |
26 | 脸型:<view | 26 | 脸型:<view |
27 | v-for="(item,index) in tag.prod_tag_face" | 27 | v-for="(item,index) in tag.prod_tag_face" |
28 | :key="index" | 28 | :key="index" |
29 | > | 29 | > |
30 | {{item.label}}<text v-if="index !== tag.prod_tag_face.length - 1">/</text> | 30 | {{item.label}}<text v-if="index !== tag.prod_tag_face.length - 1">/</text> |
31 | </view> | 31 | </view> |
32 | </view> | 32 | </view> |
33 | </view> | 33 | </view> |
34 | <view v-if="tag.prod_tag_freesend && tag.prod_tag_freesend.length !== 0"> | 34 | <view v-if="tag.prod_tag_freesend && tag.prod_tag_freesend.length !== 0"> |
35 | <view> | 35 | <view> |
36 | 赠品:<view | 36 | 赠品:<view |
37 | v-for="(item,index) in tag.prod_tag_freesend" | 37 | v-for="(item,index) in tag.prod_tag_freesend" |
38 | :key="index" | 38 | :key="index" |
39 | > | 39 | > |
40 | {{item.label}}<text v-if="index !== tag.prod_tag_freesend.length - 1">/</text> | 40 | {{item.label}}<text v-if="index !== tag.prod_tag_freesend.length - 1">/</text> |
41 | </view> | 41 | </view> |
42 | </view> | 42 | </view> |
43 | </view> | 43 | </view> |
44 | <view v-if="tag.prod_tag_insurance && tag.prod_tag_insurance.length !== 0"> | 44 | <view v-if="tag.prod_tag_insurance && tag.prod_tag_insurance.length !== 0"> |
45 | <view> | 45 | <view> |
46 | 保险:<view | 46 | 保险:<view |
47 | v-for="(item,index) in tag.prod_tag_insurance" | 47 | v-for="(item,index) in tag.prod_tag_insurance" |
48 | :key="index" | 48 | :key="index" |
49 | > | 49 | > |
50 | {{item.label}}<text v-if="index !== tag.prod_tag_insurance.length - 1">/</text> | 50 | {{item.label}}<text v-if="index !== tag.prod_tag_insurance.length - 1">/</text> |
51 | </view> | 51 | </view> |
52 | </view> | 52 | </view> |
53 | </view> | 53 | </view> |
54 | <view v-if="tag.prod_tag_metal && tag.prod_tag_metal.length !== 0"> | 54 | <view v-if="tag.prod_tag_metal && tag.prod_tag_metal.length !== 0"> |
55 | <view> | 55 | <view> |
56 | 材质:<view | 56 | 材质:<view |
57 | v-for="(item,index) in tag.prod_tag_metal" | 57 | v-for="(item,index) in tag.prod_tag_metal" |
58 | :key="index" | 58 | :key="index" |
59 | > | 59 | > |
60 | {{item.label}}<text v-if="index !== tag.prod_tag_metal.length - 1">/</text> | 60 | {{item.label}}<text v-if="index !== tag.prod_tag_metal.length - 1">/</text> |
61 | </view> | 61 | </view> |
62 | </view> | 62 | </view> |
63 | </view> | 63 | </view> |
64 | <view v-if="tag.prod_tag_personal && tag.prod_tag_personal.length !== 0"> | 64 | <view v-if="tag.prod_tag_personal && tag.prod_tag_personal.length !== 0"> |
65 | <view> | 65 | <view> |
66 | 个性:<view | 66 | 个性:<view |
67 | v-for="(item,index) in tag.prod_tag_personal" | 67 | v-for="(item,index) in tag.prod_tag_personal" |
68 | :key="index" | 68 | :key="index" |
69 | > | 69 | > |
70 | {{item.label}}<text v-if="index !== tag.prod_tag_personal.length - 1">/</text> | 70 | {{item.label}}<text v-if="index !== tag.prod_tag_personal.length - 1">/</text> |
71 | </view> | 71 | </view> |
72 | </view> | 72 | </view> |
73 | </view> | 73 | </view> |
74 | <view v-if="tag.prod_tag_sense && tag.prod_tag_sense.length !== 0"> | 74 | <view v-if="tag.prod_tag_sense && tag.prod_tag_sense.length !== 0"> |
75 | <view> | 75 | <view> |
76 | 场景:<view | 76 | 场景:<view |
77 | v-for="(item,index) in tag.prod_tag_sense" | 77 | v-for="(item,index) in tag.prod_tag_sense" |
78 | :key="index" | 78 | :key="index" |
79 | > | 79 | > |
80 | {{item.label}}<text v-if="index !== tag.prod_tag_sense.length - 1">/</text> | 80 | {{item.label}}<text v-if="index !== tag.prod_tag_sense.length - 1">/</text> |
81 | </view> | 81 | </view> |
82 | </view> | 82 | </view> |
83 | </view> | 83 | </view> |
84 | <view v-if="tag.prod_tag_sex && tag.prod_tag_sex.length !== 0"> | 84 | <view v-if="tag.prod_tag_sex && tag.prod_tag_sex.length !== 0"> |
85 | <view> | 85 | <view> |
86 | 性别:<view | 86 | 性别:<view |
87 | v-for="(item,index) in tag.prod_tag_sex" | 87 | v-for="(item,index) in tag.prod_tag_sex" |
88 | :key="index" | 88 | :key="index" |
89 | > | 89 | > |
90 | {{item.label}}<text v-if="index !== tag.prod_tag_sex.length - 1">/</text> | 90 | {{item.label}}<text v-if="index !== tag.prod_tag_sex.length - 1">/</text> |
91 | </view> | 91 | </view> |
92 | </view> | 92 | </view> |
93 | </view> | 93 | </view> |
94 | <view v-if="tag.prod_tag_style && tag.prod_tag_style.length !== 0"> | 94 | <view v-if="tag.prod_tag_style && tag.prod_tag_style.length !== 0"> |
95 | <view> | 95 | <view> |
96 | 风格:<view | 96 | 风格:<view |
97 | v-for="(item,index) in tag.prod_tag_style" | 97 | v-for="(item,index) in tag.prod_tag_style" |
98 | :key="index" | 98 | :key="index" |
99 | > | 99 | > |
100 | {{item.label}}<text v-if="index !== tag.prod_tag_style.length - 1">/</text> | 100 | {{item.label}}<text v-if="index !== tag.prod_tag_style.length - 1">/</text> |
101 | </view> | 101 | </view> |
102 | </view> | 102 | </view> |
103 | </view> | 103 | </view> |
104 | <view v-if="tag.prod_tag_weight && tag.prod_tag_weight.length !== 0"> | 104 | <view v-if="tag.prod_tag_weight && tag.prod_tag_weight.length !== 0"> |
105 | <view> | 105 | <view> |
106 | 重量:<view | 106 | 重量:<view |
107 | v-for="(item,index) in tag.prod_tag_weight" | 107 | v-for="(item,index) in tag.prod_tag_weight" |
108 | :key="index" | 108 | :key="index" |
109 | > | 109 | > |
110 | {{item.label}}<text v-if="index !== tag.prod_tag_weight.length - 1">/</text> | 110 | {{item.label}}<text v-if="index !== tag.prod_tag_weight.length - 1">/</text> |
111 | </view> | 111 | </view> |
112 | </view> | 112 | </view> |
113 | </view> | 113 | </view> |
114 | </view> | 114 | </view> |
115 | </template> | 115 | </template> |
116 | 116 | ||
117 | <script> | 117 | <script> |
118 | export default { | 118 | export default { |
119 | props: { | 119 | props: { |
120 | tag: Object, | 120 | tag: Object, |
121 | }, | 121 | }, |
122 | created() { | 122 | created() { |
123 | console.log('lalal') | ||
124 | console.log('tag', this) | ||
125 | }, | 123 | }, |
126 | updated() { | 124 | updated() { |
127 | console.log('lalal-2') | ||
128 | console.log('tag-2', this.tag) | ||
129 | }, | 125 | }, |
130 | } | 126 | } |
131 | </script> | 127 | </script> |
132 | 128 | ||
133 | <style lang="scss" scoped> | 129 | <style lang="scss" scoped> |
134 | .introduce { | 130 | .introduce { |
135 | margin-bottom: 4px; | 131 | margin-bottom: 4px; |
136 | view { | 132 | view { |
137 | display: flex; | 133 | display: flex; |
138 | align-content: center; | 134 | align-content: center; |
139 | font-size: 14px; | 135 | font-size: 14px; |
140 | color: #333333; | 136 | color: #333333; |
141 | } | 137 | } |
142 | span { | 138 | span { |
143 | margin-left: 6px; | 139 | margin-left: 6px; |
144 | margin-right: 5px; | 140 | margin-right: 5px; |
145 | font-family: "PingFangSC-Regular"; | 141 | font-family: "PingFangSC-Regular"; |
146 | } | 142 | } |
147 | } | 143 | } |
148 | </style> | 144 | </style> |
149 | 145 |
src/pages/details/details.vue
1 | <template> | 1 | <template> |
2 | <view class="container"> | 2 | <view class="container"> |
3 | <!-- 基础信息 --> | 3 | <!-- 基础信息 --> |
4 | <view class="basic_info"> | 4 | <view class="basic_info"> |
5 | <!-- 轮播图 --> | 5 | <!-- 轮播图 --> |
6 | <swiper | 6 | <swiper |
7 | class="swiperImage" | 7 | class="swiperImage" |
8 | :indicator-dots="true" | 8 | :indicator-dots="true" |
9 | :autoplay="true" | 9 | :autoplay="true" |
10 | :interval="4000" | 10 | :interval="4000" |
11 | :duration="500" | 11 | :duration="500" |
12 | > | 12 | > |
13 | <swiper-item | 13 | <swiper-item |
14 | v-for="(item, index) in carousel" | 14 | v-for="(item, index) in carousel" |
15 | :key="index" | 15 | :key="index" |
16 | > | 16 | > |
17 | <image | 17 | <image |
18 | :src="item" | 18 | :src="item" |
19 | mode="scaleToFill" | 19 | mode="scaleToFill" |
20 | ></image> | 20 | ></image> |
21 | </swiper-item> | 21 | </swiper-item> |
22 | </swiper> | 22 | </swiper> |
23 | <!-- 产品价格及购买人数 --> | 23 | <!-- 产品价格及购买人数 --> |
24 | <view class="info_pay"> | 24 | <view class="info_pay"> |
25 | <view>¥{{goodsInfo.price || '暂无'}}<span | 25 | <view>¥{{goodsInfo.price || '暂无'}}<span |
26 | v-if="goodsInfo.discountPrice" | 26 | v-if="goodsInfo.discountPrice" |
27 | class="info_pay_discount" | 27 | class="info_pay_discount" |
28 | >¥{{goodsInfo.discountPrice}}</span></view> | 28 | >¥{{goodsInfo.discountPrice}}</span></view> |
29 | <span class="info_pay_number">{{goodsInfo.tradeNumber || '暂无'}}人购买过</span> | 29 | <span class="info_pay_number">{{goodsInfo.tradeNumber || '暂无'}}人购买过</span> |
30 | </view> | 30 | </view> |
31 | <!-- 产品名称 --> | 31 | <!-- 产品名称 --> |
32 | <view class="info_name"> | 32 | <view class="info_name"> |
33 | <text class="info_name_name">{{goodsInfo.name || '暂无'}}</text> | 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 | <image src="/static/img/detail/share-icon.png"></image> | 38 | <image src="/static/img/detail/share-icon.png"></image> |
36 | <text>分享</text> | 39 | <text>分享</text> |
37 | </view> | 40 | </view> |
38 | </view> | 41 | </view> |
39 | <!-- 产品售后信息 --> | 42 | <!-- 产品售后信息 --> |
40 | <view class="info_after"> | 43 | <view class="info_after"> |
41 | <span>支持7天无理由退货</span> | 44 | <span>支持7天无理由退货</span> |
42 | <span>顺丰发货</span> | 45 | <span>顺丰发货</span> |
43 | <span>30天质量保证</span> | 46 | <span>30天质量保证</span> |
44 | </view> | 47 | </view> |
45 | </view> | 48 | </view> |
46 | <!-- 详细信息 --> | 49 | <!-- 详细信息 --> |
47 | <view class="detail_info"> | 50 | <view class="detail_info"> |
48 | <!-- 详细信息菜单 --> | 51 | <!-- 详细信息菜单 --> |
49 | <view class="screen_bar"> | 52 | <view class="screen_bar"> |
50 | <view | 53 | <view |
51 | v-for="(item, index) in screenItems" | 54 | v-for="(item, index) in screenItems" |
52 | :key="index" | 55 | :key="index" |
53 | @click="tabChange(index)" | 56 | @click="tabChange(index)" |
54 | > | 57 | > |
55 | <view | 58 | <view |
56 | class="screen_item" | 59 | class="screen_item" |
57 | v-bind:class="{ item_active: item_current === index }" | 60 | v-bind:class="{ item_active: item_current === index }" |
58 | >{{ screenItems[index] || '暂无' }}</view> | 61 | >{{ screenItems[index] || '暂无' }}</view> |
59 | </view> | 62 | </view> |
60 | </view> | 63 | </view> |
61 | <!-- 商品介绍 --> | 64 | <!-- 商品介绍 --> |
62 | <view | 65 | <view |
63 | class="screen_item" | 66 | class="screen_item" |
64 | v-if="item_current === 0" | 67 | v-if="item_current === 0" |
65 | > | 68 | > |
66 | <Introduce :tag="tag" /> | 69 | <Introduce :tag="tag" /> |
67 | </view> | 70 | </view> |
68 | <!-- 规格参数 --> | 71 | <!-- 规格参数 --> |
69 | <view | 72 | <view |
70 | class="screen_item" | 73 | class="screen_item" |
71 | v-if="item_current === 1" | 74 | v-if="item_current === 1" |
72 | > | 75 | > |
73 | <view class="specification"> | 76 | <view class="specification"> |
74 | <view | 77 | <view |
75 | class="spe_item" | 78 | class="spe_item" |
76 | v-for="(item, index) in specification" | 79 | v-for="(item, index) in specification" |
77 | :key="index" | 80 | :key="index" |
78 | > | 81 | > |
79 | <image | 82 | <image |
80 | class="spe_image" | 83 | class="spe_image" |
81 | v-bind:src="item.img" | 84 | v-bind:src="item.img" |
82 | ></image> | 85 | ></image> |
83 | <span>{{item.standard || '暂无'}}</span> | 86 | <span>{{item.standard || '暂无'}}</span> |
84 | <span>{{item.slength || '暂无'}}</span> | 87 | <span>{{item.slength || '暂无'}}</span> |
85 | </view> | 88 | </view> |
86 | </view> | 89 | </view> |
87 | </view> | 90 | </view> |
88 | <!-- 售后保障 --> | 91 | <!-- 售后保障 --> |
89 | <view | 92 | <view |
90 | class="screen_item" | 93 | class="screen_item" |
91 | v-if="item_current === 2" | 94 | v-if="item_current === 2" |
92 | > | 95 | > |
93 | <AfterSails /> | 96 | <AfterSails /> |
94 | </view> | 97 | </view> |
95 | </view> | 98 | </view> |
96 | <!-- 评价 --> | 99 | <!-- 评价 --> |
97 | <template v-if="item_current !== 2"> | 100 | <template v-if="item_current !== 2"> |
98 | <view class="evaluate"> | 101 | <view class="evaluate"> |
99 | <!-- 标题 --> | 102 | <!-- 标题 --> |
100 | <view class="evaluate_title"> | 103 | <view class="evaluate_title"> |
101 | <view><span>宝贝好评率</span><span class="title_rate">{{evaluate.rate}}</span></view> | 104 | <view><span>宝贝好评率</span><span class="title_rate">{{evaluate.rate}}</span></view> |
102 | <!-- 星星 --> | 105 | <!-- 星星 --> |
103 | <view class="evaluate_star"> | 106 | <view class="evaluate_star"> |
104 | <view | 107 | <view |
105 | class="star" | 108 | class="star" |
106 | v-for="(item, index) in evaluate.star" | 109 | v-for="(item, index) in evaluate.star" |
107 | :key="index" | 110 | :key="index" |
108 | > | 111 | > |
109 | <image | 112 | <image |
110 | src="../../static/img/detail/d_star.png" | 113 | src="../../static/img/detail/d_star.png" |
111 | mode="aspectFill" | 114 | mode="aspectFill" |
112 | style="height: 26rpx; width: 28rpx;" | 115 | style="height: 26rpx; width: 28rpx;" |
113 | ></image> | 116 | ></image> |
114 | </view> | 117 | </view> |
115 | </view> | 118 | </view> |
116 | </view> | 119 | </view> |
117 | <!-- 标签 --> | 120 | <!-- 标签 --> |
118 | <view class="evaluate_tag"> | 121 | <view class="evaluate_tag"> |
119 | <view | 122 | <view |
120 | v-for="(item, index) in evaluate.tag" | 123 | v-for="(item, index) in evaluate.tag" |
121 | :key="index" | 124 | :key="index" |
122 | >{{item.name}}</view> | 125 | >{{item.name}}</view> |
123 | </view> | 126 | </view> |
124 | </view> | 127 | </view> |
125 | </template> | 128 | </template> |
126 | <!-- 商品详情页 --> | 129 | <!-- 商品详情页 --> |
127 | <template v-if="current !==2"> | 130 | <template v-if="current !==2"> |
128 | <view class="more_info"> | 131 | <view class="more_info"> |
129 | <view | 132 | <view |
130 | class="more_fixed1" | 133 | class="more_fixed1" |
131 | @click="consolg(goodInfo.prodIntro1)" | 134 | @click="consolg(goodInfo.prodIntro1)" |
132 | > | 135 | > |
133 | <image src="/static/img/detail/hr.png"></image> | 136 | <image src="/static/img/detail/hr.png"></image> |
134 | <view>商品详情</view> | 137 | <view>商品详情</view> |
135 | <image src="/static/img/detail/hr.png"></image> | 138 | <image src="/static/img/detail/hr.png"></image> |
136 | </view> | 139 | </view> |
137 | <view | 140 | <view |
138 | class="more_all" | 141 | class="more_all" |
139 | v-html="more" | 142 | v-html="more" |
140 | > | 143 | > |
141 | </view> | 144 | </view> |
142 | </view> | 145 | </view> |
143 | </template> | 146 | </template> |
144 | <!-- 底部菜单 --> | 147 | <!-- 底部菜单 --> |
145 | <view class="menu"> | 148 | <view class="menu"> |
146 | <view | 149 | <view |
147 | @tap="toCart()" | 150 | @tap="toCart()" |
148 | class="menu_1" | 151 | class="menu_1" |
149 | > | 152 | > |
150 | <view class="cart_icon"> | 153 | <view class="cart_icon"> |
151 | <image src="/static/tab-cart.png" /> | 154 | <image src="/static/tab-cart.png" /> |
152 | <text>{{cartNumber}}</text> | 155 | <text>{{cartNumber}}</text> |
153 | </view> | 156 | </view> |
154 | <view class="menu_image">购物车</view> | 157 | <view class="menu_image">购物车</view> |
155 | </view> | 158 | </view> |
156 | <view class="menu_2"> | 159 | <view class="menu_2"> |
157 | <view | 160 | <view |
158 | class="menu_input" | 161 | class="menu_input" |
159 | @tap="showBottom(1)" | 162 | @tap="showBottom(1)" |
160 | >加入购物车</view> | 163 | >加入购物车</view> |
161 | <view | 164 | <view |
162 | class="menu_now" | 165 | class="menu_now" |
163 | @click="showBottom(2)" | 166 | @click="showBottom(2)" |
164 | >立即购买</view> | 167 | >立即购买</view> |
165 | </view> | 168 | </view> |
166 | </view> | 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 | </view> | 197 | </view> |
168 | </template> | 198 | </template> |
169 | 199 | ||
170 | <script> | 200 | <script> |
171 | import store from '@/store' | 201 | import store from '@/store' |
172 | import Introduce from './components/Introduce' // 商品介绍基本信息 | 202 | import Introduce from './components/Introduce' // 商品介绍基本信息组件 |
173 | import AfterSails from './components/AfterSails' // 售后保障组件 | 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 | export default { | 208 | export default { |
177 | components: { | 209 | components: { |
178 | Introduce, | 210 | Introduce, |
179 | AfterSails, | 211 | AfterSails, |
212 | // BottomSheet, | ||
213 | uniPopupShare, | ||
214 | uniPopupPost, | ||
180 | }, | 215 | }, |
181 | data () { | 216 | data () { |
182 | return { | 217 | return { |
183 | pid: 7, // 产品ID | 218 | pid: 7, // 产品ID |
184 | skId: undefined, // skuId | 219 | skId: undefined, // skuId |
185 | // 详细信息菜单 | 220 | // 详细信息菜单 |
186 | item_current: 0, | 221 | item_current: 0, |
187 | screenItems: [ | 222 | screenItems: [ |
188 | '商品介绍', | 223 | '商品介绍', |
189 | '规格参数', | 224 | '规格参数', |
190 | '售后保障', | 225 | '售后保障', |
191 | ], | 226 | ], |
227 | showPostImg: false, // 是否展示分享海报 | ||
192 | } | 228 | } |
193 | }, | 229 | }, |
194 | onLoad({ pid = this.pid, sk_id: skId }) { | 230 | onLoad({ pid = this.pid, sk_id: skId }) { |
195 | // 根据页面传参请求页面数据 | 231 | // 根据页面传参请求页面数据 |
196 | this.pid = pid | 232 | this.pid = pid |
197 | this.skId = skId | 233 | this.skId = skId |
198 | 234 | ||
199 | // 获取产品详情 | 235 | // 获取产品详情 |
200 | this.getDetails({ pid, skId }) | 236 | this.getDetails({ pid, skId }) |
201 | // 获取购物车数据 | 237 | // 获取购物车数据 |
202 | this.getCartNum() | 238 | this.getCartNum() |
203 | }, | 239 | }, |
204 | computed: { | 240 | computed: { |
205 | // 获取轮播图数据 | 241 | // 获取轮播图数据 |
206 | carousel() { | 242 | carousel() { |
207 | return this.$store.state.details.carousel | 243 | return this.$store.state.details.carousel |
208 | }, | 244 | }, |
209 | // 商品基本信息 | 245 | // 商品基本信息 |
210 | goodsInfo() { | 246 | goodsInfo() { |
211 | return this.$store.state.details.goodsInfo | 247 | return this.$store.state.details.goodsInfo |
212 | }, | 248 | }, |
213 | // 商品介绍商品标签 | 249 | // 商品介绍商品标签 |
214 | tag() { | 250 | tag() { |
215 | return this.$store.state.details.tag | 251 | return this.$store.state.details.tag |
216 | }, | 252 | }, |
217 | // 规格参数 | 253 | // 规格参数 |
218 | specification() { | 254 | specification() { |
219 | return this.$store.state.details.specification | 255 | return this.$store.state.details.specification |
220 | }, | 256 | }, |
221 | // 评价 | 257 | // 评价 |
222 | evaluate() { | 258 | evaluate() { |
223 | return this.$store.state.details.evaluate | 259 | return this.$store.state.details.evaluate |
224 | }, | 260 | }, |
225 | // 商品详情 | 261 | // 商品详情 |
226 | more() { | 262 | more() { |
227 | return this.$store.state.details.more | 263 | return this.$store.state.details.more |
228 | }, | 264 | }, |
229 | // 购物车数目 | 265 | // 购物车数目 |
230 | cartNumber() { | 266 | cartNumber() { |
231 | return this.$store.state.details.cartNumber | 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 | methods: { | 278 | methods: { |
235 | // 获取产品详情 | 279 | // 获取产品详情 |
236 | getDetails({ pid, skId }) { | 280 | getDetails({ pid, skId }) { |
237 | store.dispatch('details/details', { | 281 | store.dispatch('details/details', { |
238 | pid, | 282 | pid, |
239 | sk_id: skId, | 283 | sk_id: skId, |
240 | }) | 284 | }) |
241 | }, | 285 | }, |
242 | // 获取购物车数目 | 286 | // 获取购物车数目 |
243 | getCartNum() { | 287 | getCartNum() { |
244 | store.dispatch('details/getCartNumber') | 288 | store.dispatch('details/getCartNumber') |
245 | }, | 289 | }, |
246 | // 切换详细信息菜单 | 290 | // 切换详细信息菜单 |
247 | tabChange (e) { | 291 | tabChange (e) { |
248 | if (this.current !== e) { | 292 | if (this.current !== e) { |
249 | this.item_current = e | 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 | </script> | 395 | </script> |
255 | 396 | ||
256 | <style lang="scss"> | 397 | <style lang="scss"> |
257 | .container { | 398 | .container { |
258 | background-color: #f8f8f8; | 399 | background-color: #f8f8f8; |
259 | font-family: "PingFangSC-Regular"; | 400 | font-family: "PingFangSC-Regular"; |
260 | // 板块样式 | 401 | // 板块样式 |
261 | > view { | 402 | > view { |
262 | background: #ffffff; | 403 | background: #ffffff; |
263 | margin-bottom: 10px; | 404 | margin-bottom: 10px; |
264 | padding: 8px 20px 8px 20px; | 405 | padding: 8px 20px 8px 20px; |
265 | box-sizing: border-box; | 406 | box-sizing: border-box; |
266 | } | 407 | } |
267 | // 基础信息板块 | 408 | // 基础信息板块 |
268 | .basic_info { | 409 | .basic_info { |
269 | // 轮播图 | 410 | // 轮播图 |
270 | .swiperImage { | 411 | .swiperImage { |
271 | width: 684rpx; | 412 | width: 684rpx; |
272 | height: 480rpx; | 413 | height: 480rpx; |
273 | image { | 414 | image { |
274 | max-width: 100%; | 415 | max-width: 100%; |
275 | max-height: 100%; | 416 | max-height: 100%; |
276 | border-radius: 16rpx; | 417 | border-radius: 16rpx; |
277 | } | 418 | } |
278 | } | 419 | } |
279 | // 产品价格及购买人数 | 420 | // 产品价格及购买人数 |
280 | .info_pay { | 421 | .info_pay { |
281 | color: #eb5d3b; | 422 | color: #eb5d3b; |
282 | font-size: 18px; | 423 | font-size: 18px; |
283 | margin-top: 5px; | 424 | margin-top: 5px; |
284 | font-family: "PingFangSC-Semibold"; | 425 | font-family: "PingFangSC-Semibold"; |
285 | display: flex; | 426 | display: flex; |
286 | justify-content: space-between; | 427 | justify-content: space-between; |
287 | .info_pay_discount { | 428 | .info_pay_discount { |
288 | text-decoration: line-through; | 429 | text-decoration: line-through; |
289 | margin-left: 8rpx; | 430 | margin-left: 8rpx; |
290 | color: #999; | 431 | color: #999; |
291 | font-size: 14px; | 432 | font-size: 14px; |
292 | } | 433 | } |
293 | .info_pay_number { | 434 | .info_pay_number { |
294 | color: #999; | 435 | color: #999; |
295 | font-size: 14px; | 436 | font-size: 14px; |
437 | font-family: PingFangSC-Regular; | ||
296 | } | 438 | } |
297 | } | 439 | } |
298 | // 产品名称 | 440 | // 产品名称 |
299 | .info_name { | 441 | .info_name { |
300 | margin-top: 5px; | 442 | margin-top: 5px; |
301 | display: flex; | 443 | display: flex; |
302 | justify-content: space-between; | 444 | justify-content: space-between; |
303 | .info_name_name { | 445 | .info_name_name { |
304 | margin-right: 10px; | 446 | margin-right: 10px; |
305 | font-size: 16px; | 447 | font-size: 16px; |
306 | font-family: "PingFangSC-Semibold"; | 448 | font-family: "PingFangSC-Semibold"; |
307 | max-width: 592rpx; | 449 | max-width: 592rpx; |
308 | } | 450 | } |
309 | .info_name_share { | 451 | .info_name_share { |
310 | display: flex; | 452 | display: flex; |
311 | flex-direction: column; | 453 | flex-direction: column; |
312 | justify-content: space-between; | 454 | justify-content: space-between; |
313 | align-items: center; | 455 | align-items: center; |
314 | margin-top: 14rpx; | 456 | margin-top: 14rpx; |
315 | > image { | 457 | > image { |
316 | height: 40rpx; | 458 | height: 40rpx; |
317 | width: 40rpx; | 459 | width: 40rpx; |
318 | } | 460 | } |
319 | > text { | 461 | > text { |
320 | font-family: PingFangSC-Regular; | 462 | font-family: PingFangSC-Regular; |
321 | font-size: 12px; | 463 | font-size: 12px; |
322 | color: #999; | 464 | color: #999; |
323 | letter-spacing: -0.23px; | 465 | letter-spacing: -0.23px; |
324 | } | 466 | } |
325 | } | 467 | } |
326 | } | 468 | } |
327 | // 售后服务 | 469 | // 售后服务 |
328 | .info_after { | 470 | .info_after { |
329 | font-size: 10px; | 471 | font-size: 10px; |
330 | color: #999; | 472 | color: #999; |
331 | margin-top: 20rpx; | 473 | margin-top: 20rpx; |
332 | > span { | 474 | > span { |
333 | height: 14px; | 475 | height: 14px; |
334 | margin-right: 10px; | 476 | margin-right: 10px; |
335 | } | 477 | } |
336 | } | 478 | } |
337 | } | 479 | } |
338 | // 详细信息 | 480 | // 详细信息 |
339 | .detail_info { | 481 | .detail_info { |
340 | margin-bottom: 20rpx; | 482 | margin-bottom: 20rpx; |
341 | .screen_bar { | 483 | .screen_bar { |
342 | width: 670rpx; | 484 | width: 670rpx; |
343 | margin-top: 20rpx; | 485 | margin-top: 20rpx; |
344 | margin-bottom: 24rpx; | 486 | margin-bottom: 24rpx; |
345 | display: flex; | 487 | display: flex; |
346 | flex-direction: row; | 488 | flex-direction: row; |
347 | justify-content: space-between; | 489 | justify-content: space-between; |
348 | align-items: center; | 490 | align-items: center; |
349 | font-size: 14px; | 491 | font-size: 14px; |
350 | color: #333333; | 492 | color: #333333; |
351 | transition: all 0.2s; | 493 | transition: all 0.2s; |
352 | } | 494 | } |
353 | .item_active { | 495 | .item_active { |
354 | border-bottom: 4rpx solid #ff6b4a; | 496 | border-bottom: 4rpx solid #ff6b4a; |
355 | } | 497 | } |
356 | .screen_item { | 498 | .screen_item { |
357 | font-size: 32rpx; | 499 | font-size: 32rpx; |
358 | color: #333333; | 500 | color: #333333; |
359 | display: flex; | 501 | display: flex; |
360 | transition: all 0.2s; | 502 | transition: all 0.2s; |
361 | // 规格参数 | 503 | // 规格参数 |
362 | .specification { | 504 | .specification { |
363 | margin-bottom: 4px; | 505 | margin-bottom: 4px; |
364 | .spe_item { | 506 | .spe_item { |
365 | image { | 507 | image { |
366 | width: 50px; | 508 | width: 50px; |
367 | height: 25px; | 509 | height: 25px; |
368 | margin-right: 6px; | 510 | margin-right: 6px; |
369 | vertical-align: middle; | 511 | vertical-align: middle; |
370 | } | 512 | } |
371 | span { | 513 | span { |
372 | margin-left: 24rpx; | 514 | margin-left: 24rpx; |
373 | } | 515 | } |
374 | } | 516 | } |
375 | } | 517 | } |
376 | } | 518 | } |
377 | // | 519 | // |
378 | } | 520 | } |
379 | // 宝贝好评率 | 521 | // 宝贝好评率 |
380 | .evaluate { | 522 | .evaluate { |
381 | .evaluate_title { | 523 | .evaluate_title { |
382 | font-size: 14px; | 524 | font-size: 14px; |
383 | color: #333333; | 525 | color: #333333; |
384 | display: flex; | 526 | display: flex; |
385 | justify-content: space-between; | 527 | justify-content: space-between; |
386 | .title_rate { | 528 | .title_rate { |
387 | margin-left: 10rpx; | 529 | margin-left: 10rpx; |
388 | } | 530 | } |
389 | .evaluate_star { | 531 | .evaluate_star { |
390 | width: 90px; | 532 | width: 90px; |
391 | display: flex; | 533 | display: flex; |
392 | align-items: center; | 534 | align-items: center; |
393 | justify-content: space-between; | 535 | justify-content: space-between; |
394 | } | 536 | } |
395 | view { | 537 | view { |
396 | font-size: 14px; | 538 | font-size: 14px; |
397 | color: #333333; | 539 | color: #333333; |
398 | font-weight: bold; | 540 | font-weight: bold; |
399 | } | 541 | } |
400 | } | 542 | } |
401 | .evaluate_tag { | 543 | .evaluate_tag { |
402 | view { | 544 | view { |
403 | display: inline-block; | 545 | display: inline-block; |
404 | margin-right: 20rpx; | 546 | margin-right: 20rpx; |
405 | min-width: 180rpx; | 547 | min-width: 180rpx; |
406 | margin-top: 10px; | 548 | margin-top: 10px; |
407 | height: 48rpx; | 549 | height: 48rpx; |
408 | background: #f2f2f2; | 550 | background: #f2f2f2; |
409 | border-radius: 2px; | 551 | border-radius: 2px; |
410 | font-family: PingFangSC-Regular; | 552 | font-family: PingFangSC-Regular; |
411 | font-size: 12px; | 553 | font-size: 12px; |
412 | color: #666666; | 554 | color: #666666; |
413 | letter-spacing: -0.23px; | 555 | letter-spacing: -0.23px; |
414 | text-align: center; | 556 | text-align: center; |
415 | padding: 0 48rpx; | 557 | padding: 0 48rpx; |
416 | line-height: 48rpx; | 558 | line-height: 48rpx; |
417 | } | 559 | } |
418 | } | 560 | } |
419 | } | 561 | } |
420 | // 商品详情 | 562 | // 商品详情 |
421 | .more_info { | 563 | .more_info { |
422 | .more_fixed1 { | 564 | .more_fixed1 { |
423 | display: flex; | 565 | display: flex; |
424 | justify-content: space-between; | 566 | justify-content: space-between; |
425 | align-content: center; | 567 | align-content: center; |
426 | margin-bottom: 12px; | 568 | margin-bottom: 12px; |
427 | view { | 569 | view { |
428 | font-size: 14px; | 570 | font-size: 14px; |
429 | color: #333333; | 571 | color: #333333; |
430 | font-weight: bold; | 572 | font-weight: bold; |
431 | font-family: "PingFangSC-Medium"; | 573 | font-family: "PingFangSC-Medium"; |
432 | line-height: 24px; | 574 | line-height: 24px; |
433 | } | 575 | } |
434 | image { | 576 | image { |
435 | width: 240rpx; | 577 | width: 240rpx; |
436 | height: 3px; | 578 | height: 3px; |
437 | margin-top: 10px; | 579 | margin-top: 10px; |
438 | } | 580 | } |
439 | } | 581 | } |
440 | .more_all { | 582 | .more_all { |
441 | width: 100%; | 583 | width: 100%; |
442 | margin-top: 30rpx; | 584 | margin-top: 30rpx; |
443 | margin-right: 30rpx; | 585 | margin-right: 30rpx; |
444 | margin-bottom: 180rpx; | 586 | margin-bottom: 180rpx; |
445 | font-family: "PingFangSC-Regular"; | 587 | font-family: "PingFangSC-Regular"; |
446 | } | 588 | } |
447 | } | 589 | } |
448 | // 菜单 | 590 | // 菜单 |
449 | .menu { | 591 | .menu { |
450 | position: fixed; | 592 | position: fixed; |
451 | bottom: 0; | 593 | bottom: 0; |
452 | height: 74px; | 594 | height: 74px; |
453 | width: 100%; | 595 | width: 100%; |
454 | background: #ffffff; | 596 | background: #ffffff; |
455 | padding: 20px 20px 8px 20px; | 597 | padding: 20px 20px 8px 20px; |
456 | font-family: "PingFangSC-Regular"; | 598 | font-family: "PingFangSC-Regular"; |
457 | box-sizing: border-box; | 599 | box-sizing: border-box; |
458 | display: flex; | 600 | display: flex; |
459 | justify-content: space-between; | 601 | justify-content: space-between; |
460 | align-content: center; | 602 | align-content: center; |
461 | margin: 0; | 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 | .menu_1 { | 608 | .menu_1 { |
463 | width: 20%; | 609 | width: 20%; |
464 | height: 100%; | 610 | height: 100%; |
465 | text-align: center; | 611 | text-align: center; |
466 | color: #989898; | 612 | color: #989898; |
467 | .cart_icon { | 613 | .cart_icon { |
468 | position: relative; | 614 | position: relative; |
469 | text { | 615 | text { |
470 | position: absolute; | 616 | position: absolute; |
471 | color: white; | 617 | color: white; |
472 | font-size: 17px; | 618 | font-size: 17px; |
473 | background-color: red; | 619 | background-color: red; |
474 | min-height: 24px; | 620 | min-height: 24px; |
475 | min-width: 24px; | 621 | min-width: 24px; |
476 | line-height: 24px; | 622 | line-height: 24px; |
477 | right: -12%; | 623 | right: -12%; |
478 | top: -12px; | 624 | top: -12px; |
479 | text-align: center; | 625 | text-align: center; |
480 | border-radius: 24px; | 626 | border-radius: 24px; |
481 | padding: 2px; | 627 | padding: 2px; |
482 | } | 628 | } |
483 | } | 629 | } |
484 | } | 630 | } |
485 | image { | 631 | image { |
486 | width: 42%; | 632 | width: 42%; |
487 | height: 26px; | 633 | height: 26px; |
488 | } | 634 | } |
489 | .menu_image { | 635 | .menu_image { |
490 | font-size: 12px; | 636 | font-size: 12px; |
491 | text-align: center; | 637 | text-align: center; |
492 | } | 638 | } |
493 | .menu_2 { | 639 | .menu_2 { |
494 | width: 74%; | 640 | width: 74%; |
495 | height: 86%; | 641 | height: 86%; |
496 | display: grid; | 642 | display: grid; |
497 | grid-template-columns: 50% 50%; | 643 | grid-template-columns: 50% 50%; |
498 | } | 644 | } |
499 | .menu_input { | 645 | .menu_input { |
500 | display: inline-flex; | 646 | display: inline-flex; |
501 | align-items: center; | 647 | align-items: center; |
502 | justify-content: space-around; | 648 | justify-content: space-around; |
503 | background: #fff0ec; | 649 | background: #fff0ec; |
504 | font-size: 16px; | 650 | font-size: 16px; |
505 | color: #ff6b4a; | 651 | color: #ff6b4a; |
506 | border-radius: 20px 0 0 20px; | 652 | border-radius: 20px 0 0 20px; |
507 | } | 653 | } |
508 | .menu_now { | 654 | .menu_now { |
509 | display: inline-flex; | 655 | display: inline-flex; |
510 | align-items: center; | 656 | align-items: center; |
511 | justify-content: space-around; | 657 | justify-content: space-around; |
512 | background: #ff6b4a; | 658 | background: #ff6b4a; |
513 | font-size: 16px; | 659 | font-size: 16px; |
514 | color: #ffffff; | 660 | color: #ffffff; |
515 | border-radius: 0 20px 20px 0; | 661 | border-radius: 0 20px 20px 0; |
516 | } | 662 | } |
517 | } | 663 | } |
518 | } | 664 | } |
519 | </style> | 665 | </style> |
520 | 666 |
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
1 | import urlAlias from '../url' | 1 | import urlAlias from '../url' |
2 | import request from '../request' | 2 | import request from '../request' |
3 | 3 | ||
4 | const { | 4 | const { |
5 | read, | 5 | read, |
6 | cartList, | 6 | cartList, |
7 | makePost, | ||
7 | } = urlAlias | 8 | } = urlAlias |
8 | 9 | ||
9 | const state = { | 10 | const state = { |
10 | // 轮播图 | 11 | // 轮播图 |
11 | carousel: [ | 12 | carousel: [ |
12 | '/static/img/detail/d9.png', | 13 | '/static/img/detail/d9.png', |
13 | ], | 14 | ], |
14 | // 商品基本信息 | 15 | // 商品基本信息 |
15 | goodsInfo: { | 16 | goodsInfo: { |
16 | name: '暂无名称', | 17 | name: '暂无名称', |
17 | price: '暂无价格', | 18 | price: '暂无价格', |
18 | discountPrice: undefined, | 19 | discountPrice: undefined, |
19 | tradeNumber: undefined, | 20 | tradeNumber: undefined, |
20 | }, | 21 | }, |
21 | // 商品介绍 | 22 | // 商品介绍 |
22 | tag: { | 23 | tag: { |
23 | prod_tag_style: [{ | 24 | prod_tag_style: [{ |
24 | label: '青春学子风', | 25 | label: '青春学子风', |
25 | value: '54', | 26 | value: '54', |
26 | }], | 27 | }], |
27 | }, | 28 | }, |
28 | // 规格参数 | 29 | // 规格参数 |
29 | specification: [ | 30 | specification: [ |
30 | { key: 'frame_width', img: '/static/img/detail/d2.png', standard: '框架宽', slength: '139mm' }, | 31 | { key: 'frame_width', img: '/static/img/detail/d2.png', standard: '框架宽', slength: '139mm' }, |
31 | { key: 'glass_width', img: '/static/img/detail/d3.png', standard: '镜片宽', slength: '51mm' }, | 32 | { key: 'glass_width', img: '/static/img/detail/d3.png', standard: '镜片宽', slength: '51mm' }, |
32 | { key: 'glass_height', img: '/static/img/detail/d4.png', standard: '镜片高', slength: '45mm' }, | 33 | { key: 'glass_height', img: '/static/img/detail/d4.png', standard: '镜片高', slength: '45mm' }, |
33 | { key: 'nose_width', img: '/static/img/detail/d5.png', standard: '鼻架宽', slength: '19mm' }, | 34 | { key: 'nose_width', img: '/static/img/detail/d5.png', standard: '鼻架宽', slength: '19mm' }, |
34 | { key: 'leg_long', img: '/static/img/detail/d6.png', standard: '框架耳长', slength: '138mm' }, | 35 | { key: 'leg_long', img: '/static/img/detail/d6.png', standard: '框架耳长', slength: '138mm' }, |
35 | { key: 'weight', img: '/static/img/detail/d7.png', standard: '框架重', slength: '19克(grams)' }, | 36 | { key: 'weight', img: '/static/img/detail/d7.png', standard: '框架重', slength: '19克(grams)' }, |
36 | ], | 37 | ], |
37 | // 评价 | 38 | // 评价 |
38 | evaluate: { | 39 | evaluate: { |
39 | rate: '100%', | 40 | rate: '100%', |
40 | star: 5, | 41 | star: 5, |
41 | tag: [{ name: '价格实惠' }], | 42 | tag: [{ name: '价格实惠' }], |
42 | }, | 43 | }, |
43 | // 商品详情 | 44 | // 商品详情 |
44 | more: '', | 45 | more: '', |
45 | // 购物车数目 | 46 | // 购物车数目 |
46 | cartNumber: 0, | 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 | const mutations = { | 53 | const mutations = { |
50 | INIT: (state, { carousel, goodsInfo, tag, specification, evaluate, more }) => { | 54 | INIT: (state, { carousel, goodsInfo, tag, specification, evaluate, more, skuList }) => { |
51 | state.carousel = carousel | 55 | state.carousel = carousel |
52 | state.goodsInfo = goodsInfo | 56 | state.goodsInfo = goodsInfo |
53 | state.tag = tag | 57 | state.tag = tag |
54 | state.specification = specification | 58 | state.specification = specification |
55 | state.evaluate = evaluate | 59 | state.evaluate = evaluate |
56 | state.more = more | 60 | state.more = more |
61 | state.skuList = skuList | ||
57 | }, | 62 | }, |
58 | CART: (state, number) => { | 63 | CART: (state, number) => { |
59 | state.cartNumber = number | 64 | state.cartNumber = number |
60 | }, | 65 | }, |
66 | POST: (state, url) => { | ||
67 | state.postUrl = url | ||
68 | }, | ||
61 | } | 69 | } |
62 | 70 | ||
63 | const actions = { | 71 | const actions = { |
64 | // 获取详情 | 72 | // 获取详情 |
65 | details({ commit, rootState }, param) { | 73 | details({ commit, rootState }, param) { |
66 | return new Promise((resolve, reject) => request({ | 74 | return new Promise((resolve, reject) => request({ |
67 | url: read, | 75 | url: read, |
68 | data: param, | 76 | data: param, |
69 | success: ({ data: { data } }) => { | 77 | success: ({ data: { data } }) => { |
70 | console.log('data.tag', data.tag) | 78 | console.log('data.tag', data.tag) |
71 | // 规格参数设置 | 79 | // 规格参数设置 |
72 | const specification = rootState.details.specification | 80 | const specification = rootState.details.specification |
73 | const parameter = { | 81 | const parameter = { |
74 | frame_width: data.frame_width, | 82 | frame_width: data.frame_width, |
75 | glass_width: data.glass_width, | 83 | glass_width: data.glass_width, |
76 | glass_height: data.glass_height, | 84 | glass_height: data.glass_height, |
77 | nose_width: data.nose_width, | 85 | nose_width: data.nose_width, |
78 | leg_long: data.leg_long, | 86 | leg_long: data.leg_long, |
79 | weight: data.weight, | 87 | weight: data.weight, |
80 | } | 88 | } |
81 | for (let index = 0; index < specification.length; index++) { | 89 | for (let index = 0; index < specification.length; index++) { |
82 | if (specification[index].key !== 'weight') { | 90 | if (specification[index].key !== 'weight') { |
83 | specification[index].slength = `${parameter[specification[index].key]}mm` | 91 | specification[index].slength = `${parameter[specification[index].key]}mm` |
84 | } else { | 92 | } else { |
85 | specification[index].slength = `${parameter[specification[index].key]}克(grams)` | 93 | specification[index].slength = `${parameter[specification[index].key]}克(grams)` |
86 | } | 94 | } |
87 | } | 95 | } |
88 | 96 | ||
89 | commit('INIT', { | 97 | commit('INIT', { |
98 | skuList: data.skuList, | ||
90 | carousel: data.pics, | 99 | carousel: data.pics, |
91 | goodsInfo: { | 100 | goodsInfo: { |
92 | name: data.p_name, | 101 | name: data.p_name, |
93 | price: data.priceArea.Min_Price, | 102 | price: data.priceArea.Min_Price, |
94 | discountPrice: data.priceArea.Min_Price - Number(data.priceArea.discount), | 103 | discountPrice: data.priceArea.Min_Price - Number(data.priceArea.discount), |
95 | tradeNumber: data.trade_num, | 104 | tradeNumber: data.trade_num, |
96 | }, | 105 | }, |
97 | tag: data.tag, | 106 | tag: data.tag, |
98 | specification, | 107 | specification, |
99 | evaluate: { | 108 | evaluate: { |
100 | rate: data.judgeInfo.good, | 109 | rate: data.judgeInfo.good, |
101 | tag: data.judge_tag, | 110 | tag: data.judge_tag, |
102 | star: parseInt(5 * Number(data.judgeInfo.good.slice(0, -1)) / 100), | 111 | star: parseInt(5 * Number(data.judgeInfo.good.slice(0, -1)) / 100), |
103 | }, | 112 | }, |
113 | // eslint-disable-next-line | ||
104 | more: data.prodIntro1.replace(/\<img/gi, '<img style="max-width:100%;height:auto"'), | 114 | more: data.prodIntro1.replace(/\<img/gi, '<img style="max-width:100%;height:auto"'), |
105 | }) | 115 | }) |
106 | resolve(data) | 116 | resolve(data) |
107 | }, | 117 | }, |
108 | fail: (res) => { | 118 | fail: (res) => { |
109 | console.log('fail status ===>', res) | 119 | console.log('fail status ===>', res) |
110 | }, | 120 | }, |
111 | })) | 121 | })) |
112 | }, | 122 | }, |
113 | // 获取购物车列表 | 123 | // 获取购物车列表 |
114 | getCartNumber({ commit }, param) { | 124 | getCartNumber({ commit }, param) { |
115 | return new Promise((resolve) => request({ | 125 | return new Promise((resolve) => request({ |
116 | url: cartList, | 126 | url: cartList, |
117 | data: param, | 127 | data: param, |
118 | success: ({ data: { data } }) => { | 128 | success: ({ data: { data } }) => { |
119 | console.log('cartData', data) | ||
120 | let number = 0 | 129 | let number = 0 |
121 | for (let index = 0; index < data.length; index++) { | 130 | for (let index = 0; index < data.length; index++) { |
122 | number += Number(data[index].num) | 131 | number += Number(data[index].num) |
123 | } | 132 | } |
124 | commit('CART', number) | 133 | commit('CART', number) |
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 | export default { | 150 | export default { |
131 | namespaced: true, | 151 | namespaced: true, |
132 | state, | 152 | state, |
133 | mutations, | 153 | mutations, |
134 | actions, | 154 | actions, |
135 | } | 155 | } |
src/store/url.js
1 | const urlAlias = { | 1 | const urlAlias = { |
2 | // 详情 | 2 | // 详情 |
3 | read: '/app/prod/read', // 获取商品信息 | 3 | read: '/app/prod/read', // 获取商品信息 |
4 | 4 | ||
5 | // 首页 | 5 | // 首页 |
6 | shopList: '/app/prod/list', // 获取首页商品列表 | 6 | shopList: '/app/prod/list', // 获取首页商品列表 |
7 | category: '/app/prod/category2', // 获取首页商品分类 | 7 | category: '/app/prod/category2', // 获取首页商品分类 |
8 | search: '/app/prod/search', // 首页搜索商品 | 8 | search: '/app/prod/search', // 首页搜索商品 |
9 | 9 | ||
10 | // 登陆 | 10 | // 登陆 |
11 | login: '/app/glass/getOpenId', // 登陆 | 11 | login: '/app/glass/getOpenId', // 登陆 |
12 | getUserInfo: '/app/glass/userinfo', // 获取用户信息 | 12 | getUserInfo: '/app/glass/userinfo', // 获取用户信息 |
13 | 13 | ||
14 | // 我的订单 | 14 | // 我的订单 |
15 | orderList: '/app/order/list', // 获取订单列表 | 15 | orderList: '/app/order/list', // 获取订单列表 |
16 | myOrderList: '/app/order/list3', // 获取订单列表 | 16 | myOrderList: '/app/order/list3', // 获取订单列表 |
17 | orderRead: '/app/order/read', // 获取订单详情 | 17 | orderRead: '/app/order/read', // 获取订单详情 |
18 | cancelOrder: '/app/order/wait/del', // 取消订单 | 18 | cancelOrder: '/app/order/wait/del', // 取消订单 |
19 | statusConfirm: '/app/order/statusConfirm', // 订单操作 | 19 | statusConfirm: '/app/order/statusConfirm', // 订单操作 |
20 | payLog: '/app/pay/log', // 调起支付 | 20 | payLog: '/app/pay/log', // 调起支付 |
21 | orderBuild: '/app/order/build', // 加购后生成订单 | 21 | orderBuild: '/app/order/build', // 加购后生成订单 |
22 | buyNow: '/app/order/buynow', // 立即购买生成订单 | 22 | buyNow: '/app/order/buynow', // 立即购买生成订单 |
23 | pay: '/app/pay/log', // 支付接口 | 23 | pay: '/app/pay/log', // 支付接口 |
24 | 24 | ||
25 | // 购物车 | 25 | // 购物车 |
26 | cartList: '/app/cart/list', // 获取购物车列表 | 26 | cartList: '/app/cart/list', // 获取购物车列表 |
27 | cartModi: '/app/cart/modi', // 修改购物车 | 27 | cartModi: '/app/cart/modi', // 修改购物车 |
28 | cartDel: '/app/cart/del', // 删除购物车 | 28 | cartDel: '/app/cart/del', // 删除购物车 |
29 | cartAdd: '/app/cart/add', // 添加购物车 | 29 | cartAdd: '/app/cart/add', // 添加购物车 |
30 | 30 | ||
31 | // 我的 | 31 | // 我的 |
32 | recommandList: '/app/prod/recommand', // 获取用户个性化推荐商品 | 32 | recommandList: '/app/prod/recommand', // 获取用户个性化推荐商品 |
33 | 33 | ||
34 | // 镜框选购页 | 34 | // 镜框选购页 |
35 | detailStandardList: '/app/prod/read', // 获取商品的详细信息 | 35 | detailStandardList: '/app/prod/read', // 获取商品的详细信息 |
36 | // 选购页 | 36 | // 选购页 |
37 | detailStandardUrl: '/app/prod/read', // 获取商品的详细信息 | 37 | detailStandardUrl: '/app/prod/read', // 获取商品的详细信息 |
38 | makePost: '/app/glass/makeProdAdvPic', // 生成分享海报 | ||
38 | 39 | ||
39 | // 地址管理 | 40 | // 地址管理 |
40 | editAddress: '/app/address/edit_address', // 编辑地址 | 41 | editAddress: '/app/address/edit_address', // 编辑地址 |
41 | addressList: '/app/address/get_address_list', // 获取用户地址列表 | 42 | addressList: '/app/address/get_address_list', // 获取用户地址列表 |
42 | getAddress: '/app/address/get_address_by_id', // 获取用户某一地址信息 | 43 | getAddress: '/app/address/get_address_by_id', // 获取用户某一地址信息 |
43 | getDefaultAddress: '/app/address/get_default_address', // 获取用户默认地址信息 | 44 | getDefaultAddress: '/app/address/get_default_address', // 获取用户默认地址信息 |
44 | 45 | ||
45 | // 用户数据 | 46 | // 用户数据 |
46 | mylovelist: '/app/user/mylovelist', // 关心的人的数据 | 47 | mylovelist: '/app/user/mylovelist', // 关心的人的数据 |
47 | myloveadd: '/app/user/myloveadd', // 添加关心的人 | 48 | myloveadd: '/app/user/myloveadd', // 添加关心的人 |
48 | myloveupdate: '/app/user/myloveupdate', // 更新关心人的数据 | 49 | myloveupdate: '/app/user/myloveupdate', // 更新关心人的数据 |
49 | } | 50 | } |
50 | 51 | ||
51 | export default urlAlias | 52 | export default urlAlias |
52 | 53 |