Showing
45 changed files
with
814 additions
and
160 deletions
@@ -5,6 +5,7 @@ import {createStore} from './store'; | @@ -5,6 +5,7 @@ import {createStore} from './store'; | ||
5 | import 'filters'; | 5 | import 'filters'; |
6 | import 'directives'; | 6 | import 'directives'; |
7 | import titleMixin from './mixins/title'; | 7 | import titleMixin from './mixins/title'; |
8 | +import downloadMixin from './mixins/download'; | ||
8 | import pluginCore from './plugins/core'; | 9 | import pluginCore from './plugins/core'; |
9 | import lazyload from 'vue-lazyload'; | 10 | import lazyload from 'vue-lazyload'; |
10 | import reportError from 'report-error'; | 11 | import reportError from 'report-error'; |
@@ -19,6 +20,7 @@ Vue.use(lazyload, { | @@ -19,6 +20,7 @@ Vue.use(lazyload, { | ||
19 | }); | 20 | }); |
20 | Vue.use(pluginCore); | 21 | Vue.use(pluginCore); |
21 | Vue.mixin(titleMixin); | 22 | Vue.mixin(titleMixin); |
23 | +Vue.mixin(downloadMixin); | ||
22 | dayjs.locale('zh-cn'); | 24 | dayjs.locale('zh-cn'); |
23 | dayjs.extend(relativeTime); | 25 | dayjs.extend(relativeTime); |
24 | 26 |
1 | +function queryString() { | ||
2 | + var vars = {}, | ||
3 | + hash, | ||
4 | + i; | ||
5 | + var hashes = window.location.search.slice(1).split('&'); | ||
6 | + | ||
7 | + for (i = 0; i < hashes.length; i++) { | ||
8 | + hash = hashes[i].split('='); | ||
9 | + vars[decodeURIComponent(hash[0])] = decodeURIComponent(hash[1]); | ||
10 | + } | ||
11 | + return vars; | ||
12 | +} | ||
13 | + | ||
1 | const getAppPath = () => { | 14 | const getAppPath = () => { |
2 | - let appPath = document.getElementById('main-wrap').dataset.apppath || 'yohobuy://yohobuy.com/goapp?openby:yohobuy={"action":"go.home","params":{"gender":"1","channel":"2"}}'; | 15 | + let params = queryString(); |
16 | + let openbyYohobuy = params['openby:yohobuy'] || ''; | ||
17 | + let appPath = ''; | ||
18 | + | ||
19 | + if (openbyYohobuy) { | ||
20 | + appPath = 'yohobuy://yohobuy.com/goapp?openby:yohobuy=' + openbyYohobuy; | ||
21 | + } else { | ||
22 | + appPath = | ||
23 | + document.getElementById('main-wrap').dataset.apppath || | ||
24 | + 'yohobuy://yohobuy.com/goapp?openby:yohobuy={"action":"go.home","params":{"gender":"1","channel":"2"}}'; | ||
25 | + } | ||
3 | 26 | ||
4 | return appPath; | 27 | return appPath; |
5 | }; | 28 | }; |
6 | 29 | ||
7 | const u = navigator.userAgent; | 30 | const u = navigator.userAgent; |
31 | +// eslint-disable-next-line no-unused-vars | ||
8 | const isFromYOHO = /m\.yohobuy\.com/i.test(document.referrer); | 32 | const isFromYOHO = /m\.yohobuy\.com/i.test(document.referrer); |
9 | -const isApp = /yoho/i.test(u) || | 33 | +const isApp = |
34 | + /yoho/i.test(u) || | ||
10 | !!window.yohoInterface || | 35 | !!window.yohoInterface || |
11 | /app_version=/i.test(location.search) || | 36 | /app_version=/i.test(location.search) || |
12 | /openrefer=/i.test(location.search); | 37 | /openrefer=/i.test(location.search); |
13 | 38 | ||
14 | const isiOS = /(iPhone|iPad|iPod|iOS)/i.test(u); // ios终端 | 39 | const isiOS = /(iPhone|iPad|iPod|iOS)/i.test(u); // ios终端 |
15 | const isAndroid = /Android/i.test(u); // android终端 | 40 | const isAndroid = /Android/i.test(u); // android终端 |
41 | +const isWechat = /MicroMessenger/i.test(navigator.userAgent); | ||
42 | +const isMobileQQ = /MQQBrowser.+QQ/i.test(navigator.userAgent); | ||
16 | const isWechatDevtool = /wechatdevtools/i.test(u); // 微信开发者工具 | 43 | const isWechatDevtool = /wechatdevtools/i.test(u); // 微信开发者工具 |
44 | +// eslint-disable-next-line no-unused-vars | ||
17 | const nodownload = document.getElementById('no-download'); // 页面不需要下载 | 45 | const nodownload = document.getElementById('no-download'); // 页面不需要下载 |
18 | 46 | ||
19 | const getIOSVersion = () => { | 47 | const getIOSVersion = () => { |
@@ -22,17 +50,22 @@ const getIOSVersion = () => { | @@ -22,17 +50,22 @@ const getIOSVersion = () => { | ||
22 | return verion ? parseInt(verion[1], 10) : 0; | 50 | return verion ? parseInt(verion[1], 10) : 0; |
23 | }; | 51 | }; |
24 | const ua = navigator.userAgent; | 52 | const ua = navigator.userAgent; |
25 | -const isOriginalChrome = /chrome\/[\d.]+ Mobile Safari\/[\d.]+/i.test(ua) && | 53 | +const isOriginalChrome = |
54 | + /chrome\/[\d.]+ Mobile Safari\/[\d.]+/i.test(ua) && | ||
26 | isAndroid && | 55 | isAndroid && |
27 | ua.indexOf('Version') < 0; | 56 | ua.indexOf('Version') < 0; |
28 | 57 | ||
29 | -const getFallUrl = (schemeUrl) => { | ||
30 | - const appPath = (schemeUrl || '').replace('yohobuy://yohobuy.com/goapp?', '') || 'openby:yohobuy={"action":"go.home","params":{"gender":"1","channel":"2"}}'; | 58 | +const getFallUrl = schemeUrl => { |
59 | + const appPath = | ||
60 | + (schemeUrl || '').replace('yohobuy://yohobuy.com/goapp?', '') || | ||
61 | + 'openby:yohobuy={"action":"go.home","params":{"gender":"1","channel":"2"}}'; | ||
31 | 62 | ||
32 | return `https://union.yoho.cn/union/app-downloads.html?${appPath}`; | 63 | return `https://union.yoho.cn/union/app-downloads.html?${appPath}`; |
33 | }; | 64 | }; |
34 | 65 | ||
35 | const checkOpenFall = (url, callFunc, noFall) => { | 66 | const checkOpenFall = (url, callFunc, noFall) => { |
67 | + let time = Date.now(); | ||
68 | + | ||
36 | callFunc(); | 69 | callFunc(); |
37 | 70 | ||
38 | const fallUrl = getFallUrl(url); | 71 | const fallUrl = getFallUrl(url); |
@@ -41,30 +74,51 @@ const checkOpenFall = (url, callFunc, noFall) => { | @@ -41,30 +74,51 @@ const checkOpenFall = (url, callFunc, noFall) => { | ||
41 | return; | 74 | return; |
42 | } | 75 | } |
43 | 76 | ||
44 | - window.location.href = fallUrl; | 77 | + window.setTimeout(function() { |
78 | + if (Date.now() - time < 1200) { | ||
79 | + window.location.href = fallUrl; | ||
80 | + } | ||
81 | + }, 1000); | ||
45 | }; | 82 | }; |
46 | 83 | ||
47 | const callIframe = (url, noFall) => { | 84 | const callIframe = (url, noFall) => { |
48 | - checkOpenFall(url, () => { | ||
49 | - window.location.href = url; | ||
50 | - }, noFall); | 85 | + checkOpenFall( |
86 | + url, | ||
87 | + () => { | ||
88 | + const ifr = document.createElement('iframe'); | ||
89 | + | ||
90 | + ifr.src = url; | ||
91 | + ifr.style.display = 'none'; | ||
92 | + document.body.appendChild(ifr); | ||
93 | + }, | ||
94 | + noFall, | ||
95 | + ); | ||
51 | }; | 96 | }; |
52 | 97 | ||
53 | const callUrl = (url, noFall) => { | 98 | const callUrl = (url, noFall) => { |
54 | - checkOpenFall(url, () => { | ||
55 | - }, noFall); | 99 | + checkOpenFall( |
100 | + url, | ||
101 | + () => { | ||
102 | + window.location.href = url; | ||
103 | + }, | ||
104 | + noFall, | ||
105 | + ); | ||
56 | }; | 106 | }; |
57 | 107 | ||
58 | const callA = (url, noFall) => { | 108 | const callA = (url, noFall) => { |
59 | - checkOpenFall(url, () => { | ||
60 | - const ca = document.createElement('a'); | ||
61 | - | ||
62 | - ca.setAttribute('href', url); | ||
63 | - ca.style.display = 'none'; | ||
64 | - document.body.appendChild(ca); | ||
65 | - | ||
66 | - ca.click(); | ||
67 | - }, noFall); | 109 | + checkOpenFall( |
110 | + url, | ||
111 | + () => { | ||
112 | + const ca = document.createElement('a'); | ||
113 | + | ||
114 | + ca.setAttribute('href', url); | ||
115 | + ca.style.display = 'none'; | ||
116 | + document.body.appendChild(ca); | ||
117 | + | ||
118 | + ca.click(); | ||
119 | + }, | ||
120 | + noFall, | ||
121 | + ); | ||
68 | }; | 122 | }; |
69 | 123 | ||
70 | const toAppPage = (appUrl, noFall) => { | 124 | const toAppPage = (appUrl, noFall) => { |
@@ -82,16 +136,23 @@ const toAppPage = (appUrl, noFall) => { | @@ -82,16 +136,23 @@ const toAppPage = (appUrl, noFall) => { | ||
82 | }; | 136 | }; |
83 | 137 | ||
84 | const canOpenApp = () => { | 138 | const canOpenApp = () => { |
85 | - if (isWechatDevtool || isApp || isFromYOHO || nodownload) { | 139 | + if (isWechatDevtool || isApp) { |
86 | return false; | 140 | return false; |
87 | } | 141 | } |
88 | return isAndroid || isiOS; | 142 | return isAndroid || isiOS; |
89 | }; | 143 | }; |
90 | 144 | ||
91 | -export default () => { | 145 | +export default function openApp() { |
92 | if (canOpenApp()) { | 146 | if (canOpenApp()) { |
93 | - let appPath = getAppPath(); | 147 | + setTimeout(function() { |
148 | + let appPath = getAppPath(); | ||
94 | 149 | ||
95 | - toAppPage(appPath, false); | 150 | + toAppPage(appPath, false); |
151 | + }, 3000); | ||
96 | } | 152 | } |
97 | -}; | 153 | +} |
154 | + | ||
155 | +// 在 android 中,不在微信和QQ和App中,打开页面 | ||
156 | +if (isAndroid && !(isMobileQQ || isWechat) && !isApp) { | ||
157 | + openApp(); | ||
158 | +} |
@@ -59,6 +59,7 @@ const yoho = { | @@ -59,6 +59,7 @@ const yoho = { | ||
59 | isAndroid: /Android/i.test(navigator.userAgent || ''), | 59 | isAndroid: /Android/i.test(navigator.userAgent || ''), |
60 | isYohoBuy: isYohoBuy, | 60 | isYohoBuy: isYohoBuy, |
61 | isWechat: /MicroMessenger/i.test(navigator.userAgent), | 61 | isWechat: /MicroMessenger/i.test(navigator.userAgent), |
62 | + isMobileQQ: /QQ/i.test(navigator.userAgent), | ||
62 | isLocal: window.location.protocol === 'yoho-protocol:' || /yoho-protocol/i.test(navigator.userAgent || ''), | 63 | isLocal: window.location.protocol === 'yoho-protocol:' || /yoho-protocol/i.test(navigator.userAgent || ''), |
63 | appVersion: getAppVersion(navigator.userAgent, ';') || getAppVersion(document.cookie, ';'), | 64 | appVersion: getAppVersion(navigator.userAgent, ';') || getAppVersion(document.cookie, ';'), |
64 | 65 |
1 | <template> | 1 | <template> |
2 | <div class="comment-item"> | 2 | <div class="comment-item"> |
3 | - <ImageFormat :lazy="false" :src="parentComment.headIco" :width="80" :height="80" class="comment-user-avatar" @click.native="toUserPage"></ImageFormat> | 3 | + <ImageFormat :lazy="false" :src="parentComment.headIco" :width="80" :height="80" class="comment-user-avatar" |
4 | + @click.native="toUserPage"></ImageFormat> | ||
4 | <div class="comment"> | 5 | <div class="comment"> |
5 | <div class="comment-nav"> | 6 | <div class="comment-nav"> |
6 | <div class="comment-nav-left"> | 7 | <div class="comment-nav-left"> |
@@ -20,20 +21,26 @@ | @@ -20,20 +21,26 @@ | ||
20 | </div> | 21 | </div> |
21 | </div> | 22 | </div> |
22 | 23 | ||
23 | - <CommentPlaceholder | 24 | + <CommentPlaceholderActionSheet |
24 | class="comment-cont" | 25 | class="comment-cont" |
25 | :dest-id="parentComment.id" | 26 | :dest-id="parentComment.id" |
27 | + :root-id="parentComment.id" | ||
26 | :pos-id="posId" | 28 | :pos-id="posId" |
27 | :article-id="articleId" | 29 | :article-id="articleId" |
28 | :add-type="1" | 30 | :add-type="1" |
29 | :user="parentComment.userName" | 31 | :user="parentComment.userName" |
30 | :column-type="columnType" | 32 | :column-type="columnType" |
31 | :share="share" | 33 | :share="share" |
32 | - @on-comment="onReply"> | 34 | + :authorUid="authorUid" |
35 | + :commentUid="parentComment.uid" | ||
36 | + commentType="parent" | ||
37 | + @on-comment="onReply" | ||
38 | + @remove-comment="onRemoveComment" | ||
39 | + > | ||
33 | {{parentComment.content}} | 40 | {{parentComment.content}} |
34 | - </CommentPlaceholder> | 41 | + </CommentPlaceholderActionSheet> |
35 | <div class="reply-main" v-if="replayShowList.length"> | 42 | <div class="reply-main" v-if="replayShowList.length"> |
36 | - <CommentPlaceholder | 43 | + <CommentPlaceholderActionSheet |
37 | tag="p" | 44 | tag="p" |
38 | class="reply-item" | 45 | class="reply-item" |
39 | v-for="(reply, replyIndex) in replayShowList" | 46 | v-for="(reply, replyIndex) in replayShowList" |
@@ -44,13 +51,19 @@ | @@ -44,13 +51,19 @@ | ||
44 | :user="reply.userName" | 51 | :user="reply.userName" |
45 | :column-type="columnType" | 52 | :column-type="columnType" |
46 | :share="share" | 53 | :share="share" |
47 | - @on-comment="onReplyChildren"> | 54 | + :authorUid="authorUid" |
55 | + :commentUid="reply.uid" | ||
56 | + :article-id="articleId" | ||
57 | + commentType="child" | ||
58 | + @on-comment="onReplyChildren" | ||
59 | + @remove-comment="onRemoveComment" | ||
60 | + > | ||
48 | <span class="reply-user">{{reply.userName}}</span> | 61 | <span class="reply-user">{{reply.userName}}</span> |
49 | <template v-if="reply.parentUserName"> | 62 | <template v-if="reply.parentUserName"> |
50 | <span>回复</span><em class="reply-to-user">@{{reply.parentUserName}}</em> | 63 | <span>回复</span><em class="reply-to-user">@{{reply.parentUserName}}</em> |
51 | </template>: | 64 | </template>: |
52 | <span>{{reply.content}}</span> | 65 | <span>{{reply.content}}</span> |
53 | - </CommentPlaceholder> | 66 | + </CommentPlaceholderActionSheet> |
54 | <p class="reply-more" v-if="moreReplyNum > 0" @click="onShowMore"> | 67 | <p class="reply-more" v-if="moreReplyNum > 0" @click="onShowMore"> |
55 | {{replyMoreText}} | 68 | {{replyMoreText}} |
56 | <i class="iconfont icon-right" v-if="!isShowAllReply"></i> | 69 | <i class="iconfont icon-right" v-if="!isShowAllReply"></i> |
@@ -61,11 +74,14 @@ | @@ -61,11 +74,14 @@ | ||
61 | </template> | 74 | </template> |
62 | 75 | ||
63 | <script> | 76 | <script> |
64 | -import {createNamespacedHelpers} from 'vuex'; | ||
65 | -const {mapActions} = createNamespacedHelpers('comment'); | 77 | +import { createNamespacedHelpers } from 'vuex'; |
78 | +import CommentPlaceholderActionSheet from './comment-placeholder-actionsheet'; | ||
79 | + | ||
80 | +const { mapActions } = createNamespacedHelpers('comment'); | ||
66 | 81 | ||
67 | export default { | 82 | export default { |
68 | name: 'CommentItem', | 83 | name: 'CommentItem', |
84 | + components: { CommentPlaceholderActionSheet }, | ||
69 | props: { | 85 | props: { |
70 | parentComment: Object, | 86 | parentComment: Object, |
71 | childrenComments: Array, | 87 | childrenComments: Array, |
@@ -75,7 +91,8 @@ export default { | @@ -75,7 +91,8 @@ export default { | ||
75 | }, | 91 | }, |
76 | share: Boolean, | 92 | share: Boolean, |
77 | posId: Number, | 93 | posId: Number, |
78 | - articleId: Number | 94 | + articleId: Number, |
95 | + authorUid: Number | ||
79 | }, | 96 | }, |
80 | data() { | 97 | data() { |
81 | return { | 98 | return { |
@@ -138,6 +155,16 @@ export default { | @@ -138,6 +155,16 @@ export default { | ||
138 | }); | 155 | }); |
139 | }, 300); | 156 | }, 300); |
140 | }, | 157 | }, |
158 | + onRemoveComment({ commentId, commentType, articleId }) { | ||
159 | + let subCount = 0; | ||
160 | + | ||
161 | + if (commentType === 'parent') { | ||
162 | + subCount = this.childrenComments.length + 1; | ||
163 | + } else { | ||
164 | + subCount = 1; | ||
165 | + } | ||
166 | + this.$emit('remove-comment', { commentId, commentType, articleId, subCount}); | ||
167 | + } | ||
141 | } | 168 | } |
142 | }; | 169 | }; |
143 | </script> | 170 | </script> |
@@ -5,14 +5,16 @@ | @@ -5,14 +5,16 @@ | ||
5 | <div class="loading" v-if="firstLoading"> | 5 | <div class="loading" v-if="firstLoading"> |
6 | <Loading></Loading> | 6 | <Loading></Loading> |
7 | </div> | 7 | </div> |
8 | - <Scroll v-else ref="scroll" :data="commentList" :scroll-events="['scroll', 'scroll-end']" :options="scrollOption" @scroll="onScrollHandle" @scroll-end="onScrollEndHandle" @pulling-up="onPullingUp"> | 8 | + <Scroll v-else ref="scroll" :data="commentList" :scroll-events="['scroll', 'scroll-end']" |
9 | + :options="scrollOption" @scroll="onScrollHandle" @scroll-end="onScrollEndHandle" | ||
10 | + @pulling-up="onPullingUp"> | ||
9 | <CommentEmpty v-if="empty"></CommentEmpty> | 11 | <CommentEmpty v-if="empty"></CommentEmpty> |
10 | <div v-else ref="commentList" class="comment-list"> | 12 | <div v-else ref="commentList" class="comment-list"> |
11 | <div ref="commentListTop" class="comment-list-top"> | 13 | <div ref="commentListTop" class="comment-list-top"> |
12 | <div ref="commentPre" class="comment-pre-list"> | 14 | <div ref="commentPre" class="comment-pre-list"> |
13 | <div | 15 | <div |
14 | - v-for="(comments, index) in commentPreList" | ||
15 | - :key="commentPreList.length - index"> | 16 | + v-for="(comments, index) in commentPreList" |
17 | + :key="commentPreList.length - index"> | ||
16 | <CommentItem | 18 | <CommentItem |
17 | v-for="comment in comments" | 19 | v-for="comment in comments" |
18 | :key="comment.parentComment.id" | 20 | :key="comment.parentComment.id" |
@@ -21,8 +23,12 @@ | @@ -21,8 +23,12 @@ | ||
21 | :column-type="columnType" | 23 | :column-type="columnType" |
22 | :pos-id="posId" | 24 | :pos-id="posId" |
23 | :article-id="articleId" | 25 | :article-id="articleId" |
26 | + :authorUid="authorUid" | ||
27 | + :commentUid="comment.parentComment.uid" | ||
24 | @on-reply="onReply" | 28 | @on-reply="onReply" |
25 | - @on-close="onClose"> | 29 | + @on-close="onClose" |
30 | + @remove-comment="onRemoveComment" | ||
31 | + > | ||
26 | </CommentItem> | 32 | </CommentItem> |
27 | </div> | 33 | </div> |
28 | </div> | 34 | </div> |
@@ -36,34 +42,42 @@ | @@ -36,34 +42,42 @@ | ||
36 | :column-type="columnType" | 42 | :column-type="columnType" |
37 | :pos-id="posId" | 43 | :pos-id="posId" |
38 | :article-id="articleId" | 44 | :article-id="articleId" |
45 | + :authorUid="authorUid" | ||
46 | + :commentUid="comment.parentComment.uid" | ||
39 | @on-reply="onReply" | 47 | @on-reply="onReply" |
40 | - @on-close="onClose"> | 48 | + @on-close="onClose" |
49 | + @remove-comment="onRemoveComment" | ||
50 | + > | ||
41 | </CommentItem> | 51 | </CommentItem> |
42 | </div> | 52 | </div> |
43 | </Scroll> | 53 | </Scroll> |
44 | </div> | 54 | </div> |
45 | </div> | 55 | </div> |
46 | <div class="comment-footer" v-if="!firstLoading"> | 56 | <div class="comment-footer" v-if="!firstLoading"> |
47 | - <CommentPlaceholder | 57 | + <CommentPlaceholderActionSheet |
48 | class="comment-input" | 58 | class="comment-input" |
49 | :dest-id="destId" | 59 | :dest-id="destId" |
50 | :pos-id="posId" | 60 | :pos-id="posId" |
51 | :article-id="articleId" | 61 | :article-id="articleId" |
52 | :add-type="0" | 62 | :add-type="0" |
53 | :column-type="columnType" | 63 | :column-type="columnType" |
64 | + :authorUid="authorUid" | ||
54 | @on-comment="onComment"> | 65 | @on-comment="onComment"> |
55 | 参与评论 | 66 | 参与评论 |
56 | - </CommentPlaceholder> | 67 | + </CommentPlaceholderActionSheet> |
57 | </div> | 68 | </div> |
58 | </div> | 69 | </div> |
59 | </template> | 70 | </template> |
60 | 71 | ||
61 | <script> | 72 | <script> |
62 | import CommentItem from './comment-item.vue'; | 73 | import CommentItem from './comment-item.vue'; |
63 | -import {Scroll, Loading} from 'cube-ui'; | ||
64 | -import {get, throttle} from 'lodash'; | ||
65 | -import {createNamespacedHelpers} from 'vuex'; | ||
66 | -const {mapActions} = createNamespacedHelpers('comment'); | 74 | +import { Scroll, Loading } from 'cube-ui'; |
75 | +import { get, throttle, findIndex } from 'lodash'; | ||
76 | +import { createNamespacedHelpers } from 'vuex'; | ||
77 | +import CommentPlaceholderActionSheet from './comment-placeholder-actionsheet'; | ||
78 | + | ||
79 | +const { mapActions } = createNamespacedHelpers('comment'); | ||
80 | +const {mapMutations: articleMapMutations } = createNamespacedHelpers('article'); | ||
67 | 81 | ||
68 | export default { | 82 | export default { |
69 | name: 'CommentList', | 83 | name: 'CommentList', |
@@ -75,7 +89,7 @@ export default { | @@ -75,7 +89,7 @@ export default { | ||
75 | }, | 89 | }, |
76 | posId: Number, | 90 | posId: Number, |
77 | articleId: Number, | 91 | articleId: Number, |
78 | - commentId: Number | 92 | + authorUid: Number |
79 | }, | 93 | }, |
80 | data() { | 94 | data() { |
81 | return { | 95 | return { |
@@ -105,6 +119,7 @@ export default { | @@ -105,6 +119,7 @@ export default { | ||
105 | }, | 119 | }, |
106 | methods: { | 120 | methods: { |
107 | ...mapActions(['fetchCommentList', 'fetchReplayList', 'postComment']), | 121 | ...mapActions(['fetchCommentList', 'fetchReplayList', 'postComment']), |
122 | + ...articleMapMutations(['SUB_ARTICLE_COMMENT_COUNT']), | ||
108 | async fetchCommentsAsync(pre) { | 123 | async fetchCommentsAsync(pre) { |
109 | let params = { | 124 | let params = { |
110 | destId: this.destId, | 125 | destId: this.destId, |
@@ -113,7 +128,7 @@ export default { | @@ -113,7 +128,7 @@ export default { | ||
113 | }; | 128 | }; |
114 | 129 | ||
115 | if (params.page < 1 || params.page > this.totalPage) { | 130 | if (params.page < 1 || params.page > this.totalPage) { |
116 | - return {code: 200}; | 131 | + return { code: 200 }; |
117 | } | 132 | } |
118 | 133 | ||
119 | if (this.commentId && (this.prePage === this.page)) { | 134 | if (this.commentId && (this.prePage === this.page)) { |
@@ -208,7 +223,7 @@ export default { | @@ -208,7 +223,7 @@ export default { | ||
208 | type: 'warn', | 223 | type: 'warn', |
209 | time: 1000 | 224 | time: 1000 |
210 | }).show(); | 225 | }).show(); |
211 | - this.$emit('on-page-ready', {success: false}); | 226 | + this.$emit('on-page-ready', { success: false }); |
212 | } | 227 | } |
213 | return result; | 228 | return result; |
214 | }, | 229 | }, |
@@ -249,7 +264,7 @@ export default { | @@ -249,7 +264,7 @@ export default { | ||
249 | this.totalPage = 1; | 264 | this.totalPage = 1; |
250 | this.$refs.scroll.scrollTo(0, 0, 200); | 265 | this.$refs.scroll.scrollTo(0, 0, 200); |
251 | this.fetchComments(); | 266 | this.fetchComments(); |
252 | - this.$emit('on-comment', {destId: this.destId}); | 267 | + this.$emit('on-comment', { destId: this.destId }); |
253 | }, | 268 | }, |
254 | async init() { | 269 | async init() { |
255 | this.page = 1; | 270 | this.page = 1; |
@@ -259,7 +274,7 @@ export default { | @@ -259,7 +274,7 @@ export default { | ||
259 | this.firstLoading = true; | 274 | this.firstLoading = true; |
260 | this.fetchComments(); | 275 | this.fetchComments(); |
261 | }, | 276 | }, |
262 | - async onReply({destId, parentId}) { | 277 | + async onReply({ destId, parentId }) { |
263 | const commentId = parentId || destId; | 278 | const commentId = parentId || destId; |
264 | 279 | ||
265 | if (!commentId) { | 280 | if (!commentId) { |
@@ -286,9 +301,42 @@ export default { | @@ -286,9 +301,42 @@ export default { | ||
286 | }, | 301 | }, |
287 | onClose() { | 302 | onClose() { |
288 | this.$emit('on-close'); | 303 | this.$emit('on-close'); |
289 | - } | 304 | + }, |
305 | + onRemoveComment({ commentId, subCount }) { | ||
306 | + for (let comments of this.commentPreList) { | ||
307 | + for (let [index, comment] of Object.entries(comments)) { | ||
308 | + if (comment.parentComment && +comment.parentComment.id === +commentId) { | ||
309 | + comments.splice(index, 1); | ||
310 | + break; | ||
311 | + } | ||
312 | + | ||
313 | + const childrenIndex = findIndex(comment.childrenComments, { id: +commentId }); | ||
314 | + | ||
315 | + if ((+index !== -1) && (childrenIndex !== -1)) { | ||
316 | + comments[index].childrenComments.splice(childrenIndex, 1); | ||
317 | + break; | ||
318 | + } | ||
319 | + } | ||
320 | + } | ||
321 | + | ||
322 | + for (let [index, comment] of Object.entries(this.commentList)) { | ||
323 | + if (comment.parentComment && +comment.parentComment.id === +commentId) { | ||
324 | + this.commentList.splice(index, 1); | ||
325 | + break; | ||
326 | + } | ||
327 | + | ||
328 | + const childrenIndex = findIndex(comment.childrenComments, { id: +commentId }); | ||
329 | + | ||
330 | + if ((+index !== -1) && childrenIndex !== -1) { | ||
331 | + this.commentList[index].childrenComments.splice(childrenIndex, 1); | ||
332 | + break; | ||
333 | + } | ||
334 | + } | ||
335 | + | ||
336 | + this.SUB_ARTICLE_COMMENT_COUNT({ articleId: this.articleId, subCount }); | ||
337 | + }, | ||
290 | }, | 338 | }, |
291 | - components: {Scroll, CommentItem, Loading} | 339 | + components: { CommentPlaceholderActionSheet, Scroll, CommentItem, Loading } |
292 | }; | 340 | }; |
293 | </script> | 341 | </script> |
294 | 342 |
1 | +<template> | ||
2 | + <div class="actionsheet" @click.capture.stop="onClick"> | ||
3 | + <CommentPlaceholder ref="placeholder" v-bind="$attrs" v-on="$listeners"> | ||
4 | + <slot></slot> | ||
5 | + </CommentPlaceholder> | ||
6 | + </div> | ||
7 | +</template> | ||
8 | + | ||
9 | + | ||
10 | +<script> | ||
11 | +import { createNamespacedHelpers } from 'vuex'; | ||
12 | +import CommentPlaceholder from './comment-placeholder'; | ||
13 | +import { get } from 'lodash'; | ||
14 | + | ||
15 | +const { mapActions } = createNamespacedHelpers('comment'); | ||
16 | + | ||
17 | +const ITEM = { | ||
18 | + comment: '回复', | ||
19 | + remove: '删除', | ||
20 | + report: '举报' | ||
21 | +}; | ||
22 | + | ||
23 | +export default { | ||
24 | + name: 'CommentPlaceholderActionSheet', | ||
25 | + components: { CommentPlaceholder }, | ||
26 | + data() { | ||
27 | + return {}; | ||
28 | + }, | ||
29 | + methods: { | ||
30 | + ...mapActions(['setCommentStatus']), | ||
31 | + async onClick() { | ||
32 | + const authorUid = this.$attrs.authorUid; | ||
33 | + const commentUid = this.$attrs.commentUid; | ||
34 | + const uid = get(await this.$sdk.getUser(), 'uid', 0); | ||
35 | + const commentId = this.$attrs['dest-id']; | ||
36 | + const articleId = this.$attrs['article-id']; | ||
37 | + const commentType = this.$attrs.commentType; | ||
38 | + let menu = []; | ||
39 | + | ||
40 | + if (authorUid === uid || commentUid === uid) { | ||
41 | + menu = [ | ||
42 | + { | ||
43 | + content: ITEM.comment | ||
44 | + }, | ||
45 | + { | ||
46 | + content: ITEM.remove | ||
47 | + }, | ||
48 | + { | ||
49 | + content: ITEM.report | ||
50 | + } | ||
51 | + ]; | ||
52 | + } else { | ||
53 | + menu = [ | ||
54 | + { | ||
55 | + content: ITEM.comment | ||
56 | + }, | ||
57 | + { | ||
58 | + content: ITEM.report | ||
59 | + } | ||
60 | + ]; | ||
61 | + } | ||
62 | + | ||
63 | + this.$createActionSheet({ | ||
64 | + data: menu, | ||
65 | + zIndex: 200, | ||
66 | + onSelect: item => { | ||
67 | + switch (item.content) { | ||
68 | + case ITEM.comment: { | ||
69 | + this.$refs.placeholder.openComentInput(); | ||
70 | + break; | ||
71 | + } | ||
72 | + case ITEM.remove: { | ||
73 | + this.setCommentStatus({ type: 1, commentId }).then(result => { | ||
74 | + if (result.code === 200) { | ||
75 | + this.$createToast({ | ||
76 | + txt: '已删除', | ||
77 | + type: 'correct', | ||
78 | + time: 2000 | ||
79 | + }).show(); | ||
80 | + this.$emit('remove-comment', { commentId, commentType, articleId }); | ||
81 | + } else { | ||
82 | + this.$createToast({ | ||
83 | + txt: '删除失败,请重试', | ||
84 | + type: 'warn', | ||
85 | + time: 2000 | ||
86 | + }).show(); | ||
87 | + } | ||
88 | + }); | ||
89 | + break; | ||
90 | + } | ||
91 | + case ITEM.report: { | ||
92 | + this.setCommentStatus({ type: 2, commentId }).then(result => { | ||
93 | + if (result.code === 200) { | ||
94 | + this.$createToast({ | ||
95 | + txt: '已举报', | ||
96 | + type: 'correct', | ||
97 | + time: 2000 | ||
98 | + }).show(); | ||
99 | + } else { | ||
100 | + this.$createToast({ | ||
101 | + txt: '举报失败,请重试', | ||
102 | + type: 'warn', | ||
103 | + time: 2000 | ||
104 | + }).show(); | ||
105 | + } | ||
106 | + }); | ||
107 | + break; | ||
108 | + } | ||
109 | + default: { | ||
110 | + // pass | ||
111 | + } | ||
112 | + } | ||
113 | + } | ||
114 | + }).show(); | ||
115 | + } | ||
116 | + } | ||
117 | +}; | ||
118 | +</script> | ||
119 | + | ||
120 | +<style lang="scss"> | ||
121 | +.cube-action-sheet-panel { | ||
122 | + margin-left: 15px; | ||
123 | + margin-right: 15px; | ||
124 | + margin-bottom: 17px; | ||
125 | + border-radius: 10px; | ||
126 | + overflow: hidden; | ||
127 | +} | ||
128 | + | ||
129 | +.cube-action-sheet-item { | ||
130 | + color: #222 !important; | ||
131 | + font-weight: bold !important; | ||
132 | +} | ||
133 | + | ||
134 | +.cube-action-sheet-cancel { | ||
135 | + span { | ||
136 | + color: #222 !important; | ||
137 | + font-weight: bold !important; | ||
138 | + } | ||
139 | +} | ||
140 | + | ||
141 | +.cube-action-sheet-space { | ||
142 | + height: 1px !important; | ||
143 | + background-color: rgb(235, 235, 235) !important; | ||
144 | +} | ||
145 | +</style> |
@@ -115,10 +115,10 @@ export default { | @@ -115,10 +115,10 @@ export default { | ||
115 | }; | 115 | }; |
116 | 116 | ||
117 | if (result.code === 200) { | 117 | if (result.code === 200) { |
118 | - this.UPDATE_ARTICLE_COMMENT_COUNT({articleId: this.destId}); | 118 | + this.UPDATE_ARTICLE_COMMENT_COUNT({articleId: this.articleId}); |
119 | 119 | ||
120 | if (this.autoUpdate && this.addType === 0) { | 120 | if (this.autoUpdate && this.addType === 0) { |
121 | - await this.fetchArticleUpdate({articleId: this.destId}); | 121 | + await this.fetchArticleUpdate({articleId: this.articleId}); |
122 | } | 122 | } |
123 | 123 | ||
124 | this.$emit('on-comment', { | 124 | this.$emit('on-comment', { |
@@ -6,7 +6,7 @@ | @@ -6,7 +6,7 @@ | ||
6 | <i class="iconfont icon-close icon" @touchend.prevent="onClose"></i> | 6 | <i class="iconfont icon-close icon" @touchend.prevent="onClose"></i> |
7 | </template> | 7 | </template> |
8 | </LayoutHeader> | 8 | </LayoutHeader> |
9 | - <CommentList ref="commentList" :dest-id="destId" :pos-id="posId" :article-id="articleId" :comment-id="commentId" :column-type="1001" @on-page-change="onPageChange" @on-comment="onComment" @on-page-ready="onPageReady" @on-close="onClose"></CommentList> | 9 | + <CommentList ref="commentList" :dest-id="destId" :pos-id="posId" :article-id="articleId" :comment-id="commentId" :column-type="1001" @on-page-change="onPageChange" @on-comment="onComment" @on-page-ready="onPageReady" @on-close="onClose" :authorUid="authorUid"></CommentList> |
10 | </Layout> | 10 | </Layout> |
11 | </template> | 11 | </template> |
12 | 12 | ||
@@ -24,7 +24,8 @@ export default { | @@ -24,7 +24,8 @@ export default { | ||
24 | posId: Number, | 24 | posId: Number, |
25 | articleId: Number, | 25 | articleId: Number, |
26 | commentId: Number, | 26 | commentId: Number, |
27 | - commentCount: Number | 27 | + commentCount: Number, |
28 | + authorUid: Number | ||
28 | }, | 29 | }, |
29 | data() { | 30 | data() { |
30 | return { | 31 | return { |
@@ -2,10 +2,12 @@ import Comment from './comment'; | @@ -2,10 +2,12 @@ import Comment from './comment'; | ||
2 | import CommentItem from './comment-item'; | 2 | import CommentItem from './comment-item'; |
3 | import CommentEmpty from './comment-empty'; | 3 | import CommentEmpty from './comment-empty'; |
4 | import CommentPlaceholder from './comment-placeholder'; | 4 | import CommentPlaceholder from './comment-placeholder'; |
5 | +import CommentPlaceholderActionSheet from './comment-placeholder-actionsheet'; | ||
5 | 6 | ||
6 | export default [ | 7 | export default [ |
7 | Comment, | 8 | Comment, |
8 | CommentItem, | 9 | CommentItem, |
9 | CommentEmpty, | 10 | CommentEmpty, |
10 | - CommentPlaceholder | 11 | + CommentPlaceholder, |
12 | + CommentPlaceholderActionSheet | ||
11 | ]; | 13 | ]; |
@@ -2,7 +2,7 @@ export default { | @@ -2,7 +2,7 @@ export default { | ||
2 | name: 'AuthComponent', | 2 | name: 'AuthComponent', |
3 | props: { | 3 | props: { |
4 | tag: String, | 4 | tag: String, |
5 | - auth: { | 5 | + requiredAuth: { |
6 | type: Boolean, | 6 | type: Boolean, |
7 | default: true | 7 | default: true |
8 | } | 8 | } |
@@ -15,17 +15,17 @@ export default { | @@ -15,17 +15,17 @@ export default { | ||
15 | 15 | ||
16 | this._lastTime = e.timeStamp; | 16 | this._lastTime = e.timeStamp; |
17 | 17 | ||
18 | - if (!this.auth) { | ||
19 | - return this.$emit('click'); | ||
20 | - } | 18 | + if (this.requiredAuth) { |
19 | + const user = await this.$sdk.getUser(); | ||
21 | 20 | ||
22 | - const user = await this.$sdk.getUser(); | ||
23 | - | ||
24 | - if (user && user.uid) { | ||
25 | - this.$emit('click', {uid: user.uid}); | 21 | + if (user && user.uid) { |
22 | + this.$emit('click', {uid: user.uid}); | ||
23 | + } else { | ||
24 | + this.$emit('cancel'); | ||
25 | + this.$sdk.goLogin(); | ||
26 | + } | ||
26 | } else { | 27 | } else { |
27 | - this.$emit('cancel'); | ||
28 | - this.$sdk.goLogin(); | 28 | + return this.$emit('click'); |
29 | } | 29 | } |
30 | } | 30 | } |
31 | }, | 31 | }, |
1 | <template> | 1 | <template> |
2 | - <AuthComponent class="btn-follow hover-opacity" :class="followClass" :auth="isAuth" @click="onFollow"> | 2 | + <AuthComponent class="btn-follow hover-opacity" :class="followClass" :requiredAuth="isAuth" @click="onFollow"> |
3 | <span>{{followText}}</span> | 3 | <span>{{followText}}</span> |
4 | </AuthComponent> | 4 | </AuthComponent> |
5 | </template> | 5 | </template> |
6 | 6 | ||
7 | <script> | 7 | <script> |
8 | -import {createNamespacedHelpers} from 'vuex'; | 8 | +import { createNamespacedHelpers } from 'vuex'; |
9 | import YAS from 'utils/yas-constants'; | 9 | import YAS from 'utils/yas-constants'; |
10 | -const {mapActions} = createNamespacedHelpers('user'); | 10 | + |
11 | +const { mapActions } = createNamespacedHelpers('user'); | ||
11 | 12 | ||
12 | export default { | 13 | export default { |
13 | name: 'WidgetFollow', | 14 | name: 'WidgetFollow', |
14 | props: { | 15 | props: { |
15 | authorUid: [Number, String], | 16 | authorUid: [Number, String], |
16 | - follow: Boolean, | 17 | + follow: [String, Boolean], |
17 | authorType: { | 18 | authorType: { |
18 | type: [Number, String], | 19 | type: [Number, String], |
19 | default: 1 | 20 | default: 1 |
@@ -25,12 +26,12 @@ export default { | @@ -25,12 +26,12 @@ export default { | ||
25 | data() { | 26 | data() { |
26 | return { | 27 | return { |
27 | loading: false, | 28 | loading: false, |
28 | - followStatus: this.follow | 29 | + followStatus: this.follow === 'Y' || this.follow === 'O' |
29 | }; | 30 | }; |
30 | }, | 31 | }, |
31 | watch: { | 32 | watch: { |
32 | follow(val) { | 33 | follow(val) { |
33 | - this.followStatus = val; | 34 | + this.followStatus = val === 'Y' || val === 'O'; |
34 | } | 35 | } |
35 | }, | 36 | }, |
36 | computed: { | 37 | computed: { |
@@ -41,7 +42,20 @@ export default { | @@ -41,7 +42,20 @@ export default { | ||
41 | }; | 42 | }; |
42 | }, | 43 | }, |
43 | followText() { | 44 | followText() { |
44 | - return this.followStatus ? '已关注' : '关注'; | 45 | + switch (this.follow) { |
46 | + case 'Y': { | ||
47 | + return '已关注'; | ||
48 | + } | ||
49 | + case 'N': { | ||
50 | + return '关注'; | ||
51 | + } | ||
52 | + case 'O': { | ||
53 | + return '已相互关注'; | ||
54 | + } | ||
55 | + default: { | ||
56 | + return '关注'; | ||
57 | + } | ||
58 | + } | ||
45 | }, | 59 | }, |
46 | isAuth() { | 60 | isAuth() { |
47 | return !this.share; | 61 | return !this.share; |
@@ -85,7 +99,7 @@ export default { | @@ -85,7 +99,7 @@ export default { | ||
85 | }).show(); | 99 | }).show(); |
86 | this.reportFellow(); | 100 | this.reportFellow(); |
87 | } | 101 | } |
88 | - this.$emit('on-follow', this.followStatus); | 102 | + this.$emit('on-follow', this.followStatus ? 'Y' : 'N'); |
89 | } else { | 103 | } else { |
90 | this.$createToast && this.$createToast({ | 104 | this.$createToast && this.$createToast({ |
91 | txt: result.message || '服务器开小差了', | 105 | txt: result.message || '服务器开小差了', |
@@ -140,5 +154,12 @@ export default { | @@ -140,5 +154,12 @@ export default { | ||
140 | > span { | 154 | > span { |
141 | line-height: 1; | 155 | line-height: 1; |
142 | } | 156 | } |
157 | + | ||
158 | + .each-follow { | ||
159 | + width: 110px; | ||
160 | + height: 50px; | ||
161 | + background-image: url("~statics/image/userpage/follow.png"); | ||
162 | + background-size: cover; | ||
163 | + } | ||
143 | } | 164 | } |
144 | </style> | 165 | </style> |
1 | <template> | 1 | <template> |
2 | <div class="icon-btn" :class="{'btn-selected': viewOption.selected}" :style="btnStyle"> | 2 | <div class="icon-btn" :class="{'btn-selected': viewOption.selected}" :style="btnStyle"> |
3 | - <AuthComponent :auth="isAuth" class="click-wrap" @click="onClick"></AuthComponent> | 3 | + <AuthComponent :requiredAuth="isAuth" class="click-wrap" @click="onClick"></AuthComponent> |
4 | <i class="iconfont" :class="iconClass" :style="iconStyle"> | 4 | <i class="iconfont" :class="iconClass" :style="iconStyle"> |
5 | <div v-if="type === 'fav'" class="praise-lottie"> | 5 | <div v-if="type === 'fav'" class="praise-lottie"> |
6 | <WidgetLottie ref="lottie" class="praise-lottie-wrap" :options="lottieOptions"></WidgetLottie> | 6 | <WidgetLottie ref="lottie" class="praise-lottie-wrap" :options="lottieOptions"></WidgetLottie> |
@@ -244,10 +244,11 @@ export default { | @@ -244,10 +244,11 @@ export default { | ||
244 | return Promise.resolve({code: 404}); | 244 | return Promise.resolve({code: 404}); |
245 | } | 245 | } |
246 | }, | 246 | }, |
247 | - onClick(evt) { | 247 | + async onClick(evt) { |
248 | if (this.share) { | 248 | if (this.share) { |
249 | return this.$links.toDownloadApp(); | 249 | return this.$links.toDownloadApp(); |
250 | } | 250 | } |
251 | + | ||
251 | if (this.syncing) { | 252 | if (this.syncing) { |
252 | return; | 253 | return; |
253 | } | 254 | } |
@@ -14,6 +14,10 @@ import sdk from 'common/sdk'; | @@ -14,6 +14,10 @@ import sdk from 'common/sdk'; | ||
14 | import links from 'utils/links'; | 14 | import links from 'utils/links'; |
15 | import openApp from 'common/open-app'; | 15 | import openApp from 'common/open-app'; |
16 | 16 | ||
17 | +if (process.env.NODE_ENV === 'development') { | ||
18 | + require('./utils/debug'); | ||
19 | +} | ||
20 | + | ||
17 | import {initClient, getYohoState} from 'utils/init-client'; | 21 | import {initClient, getYohoState} from 'utils/init-client'; |
18 | import 'statics/scss/common.scss'; | 22 | import 'statics/scss/common.scss'; |
19 | import 'statics/scss/grass-prompt.scss'; | 23 | import 'statics/scss/grass-prompt.scss'; |
apps/mixins/download.js
0 → 100644
1 | +const serverDownloadMixin = { | ||
2 | + methods: { | ||
3 | + async isDownloadBarHide() { | ||
4 | + return true; | ||
5 | + }, | ||
6 | + | ||
7 | + async isMiniapp() { | ||
8 | + return false; | ||
9 | + }, | ||
10 | + | ||
11 | + openByBrowser() { | ||
12 | + | ||
13 | + } | ||
14 | + | ||
15 | + } | ||
16 | +}; | ||
17 | + | ||
18 | +const clientDownloadMixin = { | ||
19 | + methods: { | ||
20 | + async isDownloadBarHide() { | ||
21 | + let isMiniapp = await this.isMiniapp(); | ||
22 | + | ||
23 | + if (isMiniapp) { | ||
24 | + return true; | ||
25 | + } | ||
26 | + | ||
27 | + return document.getElementById('no-download'); | ||
28 | + }, | ||
29 | + | ||
30 | + isMiniapp() { | ||
31 | + /* eslint-disable-next-line */ | ||
32 | + return this.$store.$context.env.isMiniApp; | ||
33 | + }, | ||
34 | + | ||
35 | + sleep(ns) { | ||
36 | + return new Promise(resolve => { | ||
37 | + setTimeout(resolve, ns); | ||
38 | + }); | ||
39 | + }, | ||
40 | + | ||
41 | + openByBrowser() { | ||
42 | + let appPathUrl = window.location.pathname; | ||
43 | + | ||
44 | + const query = Object.assign({}, this.$route.query, { | ||
45 | + headerid: -1, | ||
46 | + toplayoutByH5: 'Y' | ||
47 | + }); | ||
48 | + | ||
49 | + const openBy = { | ||
50 | + action: 'go.h5', | ||
51 | + params: { | ||
52 | + url: 'http://m.yohobuy.com' + appPathUrl, | ||
53 | + param: JSON.stringify(query) | ||
54 | + } | ||
55 | + }; | ||
56 | + | ||
57 | + this.$router.push({ | ||
58 | + name: 'openByBrowser', | ||
59 | + query: { | ||
60 | + 'openby:yohobuy': encodeURIComponent(JSON.stringify(openBy)), | ||
61 | + share: false | ||
62 | + } | ||
63 | + }); | ||
64 | + } | ||
65 | + } | ||
66 | +}; | ||
67 | + | ||
68 | +export default process.env.VUE_ENV === 'server' ? | ||
69 | + serverDownloadMixin : | ||
70 | + clientDownloadMixin; |
@@ -20,7 +20,7 @@ export default { | @@ -20,7 +20,7 @@ export default { | ||
20 | return; | 20 | return; |
21 | } | 21 | } |
22 | 22 | ||
23 | - let shareData = getDetailShareData(article); | 23 | + let shareData = getDetailShareData(article, this.$yoho.appVersion); |
24 | 24 | ||
25 | document && (document.title = shareData.title); | 25 | document && (document.title = shareData.title); |
26 | 26 |
@@ -3,7 +3,7 @@ | @@ -3,7 +3,7 @@ | ||
3 | <ArticleDetailHeader ref="header" class="article-detail-header" v-show="!share" :data="articleInfo" :step="headerAnimateStep" :title-step="headerTitleAnimateStep"> | 3 | <ArticleDetailHeader ref="header" class="article-detail-header" v-show="!share" :data="articleInfo" :step="headerAnimateStep" :title-step="headerTitleAnimateStep"> |
4 | <div v-if="articleInfo.articleId && !articleInfo.empty" class="title-main"> | 4 | <div v-if="articleInfo.articleId && !articleInfo.empty" class="title-main"> |
5 | <div class="title-info" :style="`transform: translate3d(0, ${viewMoreArticles ? '-50%' : '0'}, 0)`"> | 5 | <div class="title-info" :style="`transform: translate3d(0, ${viewMoreArticles ? '-50%' : '0'}, 0)`"> |
6 | - <ArticleItemHeader class="title-info-author" :share="share" :data="authorData" :more="false" @on-follow="onFollowAuthor"></ArticleItemHeader> | 6 | + <ArticleItemHeader class="title-info-author" :share="false" :data="authorData" :more="false" @on-follow="onFollowAuthor"></ArticleItemHeader> |
7 | <div class="title-info-rec">{{listTitle}}</div> | 7 | <div class="title-info-rec">{{listTitle}}</div> |
8 | </div> | 8 | </div> |
9 | </div> | 9 | </div> |
@@ -13,7 +13,7 @@ | @@ -13,7 +13,7 @@ | ||
13 | <ClientOnly> | 13 | <ClientOnly> |
14 | <Download v-if="share"></Download> | 14 | <Download v-if="share"></Download> |
15 | </ClientOnly> | 15 | </ClientOnly> |
16 | - <ArticleDeatilLong | 16 | + <ArticleDetailLong |
17 | v-if="articleInfo.sort == 2" | 17 | v-if="articleInfo.sort == 2" |
18 | ref="detailLong" | 18 | ref="detailLong" |
19 | :data="articleInfo" | 19 | :data="articleInfo" |
@@ -24,8 +24,8 @@ | @@ -24,8 +24,8 @@ | ||
24 | :pos-id="posId" | 24 | :pos-id="posId" |
25 | @on-show-more="onShowMore" | 25 | @on-show-more="onShowMore" |
26 | @on-follow="onFollowAuthor"> | 26 | @on-follow="onFollowAuthor"> |
27 | - </ArticleDeatilLong> | ||
28 | - <ArticleDeatilNote | 27 | + </ArticleDetailLong> |
28 | + <ArticleDetailNote | ||
29 | v-else | 29 | v-else |
30 | ref="detailNote" | 30 | ref="detailNote" |
31 | :data="articleInfo" | 31 | :data="articleInfo" |
@@ -37,7 +37,7 @@ | @@ -37,7 +37,7 @@ | ||
37 | @on-show-more="onShowMore" | 37 | @on-show-more="onShowMore" |
38 | @on-follow="onFollowAuthor" | 38 | @on-follow="onFollowAuthor" |
39 | @on-praise="onPraise"> | 39 | @on-praise="onPraise"> |
40 | - </ArticleDeatilNote> | 40 | + </ArticleDetailNote> |
41 | </template> | 41 | </template> |
42 | <template class="article-item" #item="{ data }"> | 42 | <template class="article-item" #item="{ data }"> |
43 | <ArticleItem2 | 43 | <ArticleItem2 |
@@ -92,8 +92,8 @@ import {getDetailShareData} from 'utils/share-handler'; | @@ -92,8 +92,8 @@ import {getDetailShareData} from 'utils/share-handler'; | ||
92 | import YAS from 'utils/yas-constants'; | 92 | import YAS from 'utils/yas-constants'; |
93 | import ArticleDetailHeader from './components/detail/article-header'; | 93 | import ArticleDetailHeader from './components/detail/article-header'; |
94 | import ArticleItemHeader from './components/article/article-item-header'; | 94 | import ArticleItemHeader from './components/article/article-item-header'; |
95 | -import ArticleDeatilLong from './components/detail/article-long'; | ||
96 | -import ArticleDeatilNote from './components/detail/article-note'; | 95 | +import ArticleDetailLong from './components/detail/article-long'; |
96 | +import ArticleDetailNote from './components/detail/article-note'; | ||
97 | import ArticleItem2 from './components/article/article-item2'; | 97 | import ArticleItem2 from './components/article/article-item2'; |
98 | import ArticleDetailFooter from './components/detail/article-footer'; | 98 | import ArticleDetailFooter from './components/detail/article-footer'; |
99 | import Download from './components/download-top'; | 99 | import Download from './components/download-top'; |
@@ -383,7 +383,7 @@ export default { | @@ -383,7 +383,7 @@ export default { | ||
383 | return; | 383 | return; |
384 | } | 384 | } |
385 | 385 | ||
386 | - Share.setShareInfo(getDetailShareData(article)); | 386 | + Share.setShareInfo(getDetailShareData(article, this.$yoho.appVersion)); |
387 | }, | 387 | }, |
388 | reportArticleShow(items) { | 388 | reportArticleShow(items) { |
389 | if (!items || !items.length) { | 389 | if (!items || !items.length) { |
@@ -469,8 +469,8 @@ export default { | @@ -469,8 +469,8 @@ export default { | ||
469 | ReplaceToHome, | 469 | ReplaceToHome, |
470 | ArticleDetailHeader, | 470 | ArticleDetailHeader, |
471 | ArticleItemHeader, | 471 | ArticleItemHeader, |
472 | - ArticleDeatilLong, | ||
473 | - ArticleDeatilNote, | 472 | + ArticleDetailLong, |
473 | + ArticleDetailNote, | ||
474 | ArticleItem2, | 474 | ArticleItem2, |
475 | MoreActionSheet, | 475 | MoreActionSheet, |
476 | ArticleDetailFooter, | 476 | ArticleDetailFooter, |
@@ -10,7 +10,7 @@ | @@ -10,7 +10,7 @@ | ||
10 | </div> | 10 | </div> |
11 | </div> | 11 | </div> |
12 | <div class="opts"> | 12 | <div class="opts"> |
13 | - <WidgetFollow :class="invisibleClass" v-if="data.hasAttention" :share="share" :author-uid="data.authorUid" :authorType="data.authorType" :follow="data.hasAttention === 'Y'" @on-follow="onFollow" :pos-id="posId"></WidgetFollow> | 13 | + <WidgetFollow :class="invisibleClass" v-if="data.hasAttention" :share="share" :author-uid="data.authorUid" :authorType="data.authorType" :follow="data.hasAttention" @on-follow="onFollow" :pos-id="posId"></WidgetFollow> |
14 | <i v-if="more" class="iconfont icon-more1" @click="onMore"></i> | 14 | <i v-if="more" class="iconfont icon-more1" @click="onMore"></i> |
15 | </div> | 15 | </div> |
16 | </div> | 16 | </div> |
@@ -173,7 +173,7 @@ export default { | @@ -173,7 +173,7 @@ export default { | ||
173 | this.reportLabel(topicId); | 173 | this.reportLabel(topicId); |
174 | }, | 174 | }, |
175 | onShare() { | 175 | onShare() { |
176 | - this.$yoho.share(getDetailShareData(this.data)); | 176 | + this.$yoho.share(getDetailShareData(this.data, this.$yoho.appVersion)); |
177 | }, | 177 | }, |
178 | onExpanding() { | 178 | onExpanding() { |
179 | if (this.data.articleType === 2) { | 179 | if (this.data.articleType === 2) { |
@@ -137,8 +137,15 @@ export default { | @@ -137,8 +137,15 @@ export default { | ||
137 | this.reportClickAvatar(); | 137 | this.reportClickAvatar(); |
138 | }, | 138 | }, |
139 | toArticlePage() { | 139 | toArticlePage() { |
140 | - if (this.share) { | ||
141 | - return this.$links.toDownloadApp(); | 140 | + if (this.isMiniapp()) { |
141 | + let url = `http://m.yohobuy.com/grass/article/${this.data.articleId}`; | ||
142 | + let h5url = `http://m.yohobuy.com?openby:yohobuy={"action":"go.h5","params":{"h5back":"${encodeURIComponent(url)}"}}`; | ||
143 | + | ||
144 | + /* eslint-disable-next-line */ | ||
145 | + wx.miniProgram.navigateTo({ | ||
146 | + url: '/pages/common/webback?url=' + encodeURIComponent(h5url) | ||
147 | + }); | ||
148 | + return; | ||
142 | } | 149 | } |
143 | 150 | ||
144 | this.$router.push({ | 151 | this.$router.push({ |
@@ -258,7 +258,7 @@ export default { | @@ -258,7 +258,7 @@ export default { | ||
258 | }, | 258 | }, |
259 | onFollow(data, follow) { | 259 | onFollow(data, follow) { |
260 | if (data.authorUid === this.currentAuthor.authorUid) { | 260 | if (data.authorUid === this.currentAuthor.authorUid) { |
261 | - this.currentAuthor.hasAttention = follow ? 'Y' : 'N'; | 261 | + this.currentAuthor.hasAttention = follow === 'Y' || follow === 'O' ? 'Y' : 'N'; |
262 | } | 262 | } |
263 | this.CHANGE_AUTHOR_FOLLOW({authorUid: data.authorUid, authorType: data.authorType, follow, type: this.type}); | 263 | this.CHANGE_AUTHOR_FOLLOW({authorUid: data.authorUid, authorType: data.authorType, follow, type: this.type}); |
264 | }, | 264 | }, |
@@ -86,7 +86,7 @@ export default { | @@ -86,7 +86,7 @@ export default { | ||
86 | } | 86 | } |
87 | }, | 87 | }, |
88 | onShare() { | 88 | onShare() { |
89 | - const share = getDetailShareData(this.data); | 89 | + const share = getDetailShareData(this.data, this.$yoho.appVersion); |
90 | 90 | ||
91 | keys(this.data.atUserInfo).forEach(k => { | 91 | keys(this.data.atUserInfo).forEach(k => { |
92 | share.desc = share.desc.replace(new RegExp(`@${k}#`, 'gm'), `${this.data.atUserInfo[k]}`); | 92 | share.desc = share.desc.replace(new RegExp(`@${k}#`, 'gm'), `${this.data.atUserInfo[k]}`); |
@@ -31,6 +31,7 @@ | @@ -31,6 +31,7 @@ | ||
31 | :commentCount="articleState.commentCount" | 31 | :commentCount="articleState.commentCount" |
32 | :share="share" | 32 | :share="share" |
33 | :pos-id="posId" | 33 | :pos-id="posId" |
34 | + :authorUid="data.authorUid" | ||
34 | @on-close="onCloseComment" | 35 | @on-close="onCloseComment" |
35 | @on-comment="onActionComment"></Comment> | 36 | @on-comment="onActionComment"></Comment> |
36 | </YohoActionSheet> | 37 | </YohoActionSheet> |
@@ -46,7 +47,7 @@ import ArticleItemSlideImage from '../article/article-item-slide-image'; | @@ -46,7 +47,7 @@ import ArticleItemSlideImage from '../article/article-item-slide-image'; | ||
46 | import ArticleDetailHeader from './article-header'; | 47 | import ArticleDetailHeader from './article-header'; |
47 | import YAS from 'utils/yas-constants'; | 48 | import YAS from 'utils/yas-constants'; |
48 | import {mapState, mapMutations, createNamespacedHelpers} from 'vuex'; | 49 | import {mapState, mapMutations, createNamespacedHelpers} from 'vuex'; |
49 | -const {mapState: mapArticleState} = createNamespacedHelpers('article'); | 50 | +const {mapState: mapArticleState, mapActions} = createNamespacedHelpers('article'); |
50 | 51 | ||
51 | let timeOutEvent = null; | 52 | let timeOutEvent = null; |
52 | 53 | ||
@@ -74,6 +75,8 @@ export default { | @@ -74,6 +75,8 @@ export default { | ||
74 | recomendProduct: [], | 75 | recomendProduct: [], |
75 | showCommentAction: false, | 76 | showCommentAction: false, |
76 | showCommentActioning: false, | 77 | showCommentActioning: false, |
78 | + productSknList: [], | ||
79 | + productEleList: [] | ||
77 | }; | 80 | }; |
78 | }, | 81 | }, |
79 | mounted() { | 82 | mounted() { |
@@ -149,6 +152,7 @@ export default { | @@ -149,6 +152,7 @@ export default { | ||
149 | }, | 152 | }, |
150 | methods: { | 153 | methods: { |
151 | ...mapMutations(['SET_STATUS_BAR_COLOR']), | 154 | ...mapMutations(['SET_STATUS_BAR_COLOR']), |
155 | + ...mapActions(['fetchProductBySknList']), | ||
152 | tStart(e) { | 156 | tStart(e) { |
153 | if (e.target.src) { | 157 | if (e.target.src) { |
154 | timeOutEvent = setTimeout(() => { | 158 | timeOutEvent = setTimeout(() => { |
@@ -22,7 +22,7 @@ | @@ -22,7 +22,7 @@ | ||
22 | <i class="iconfont icon-more1" @click="onMore"></i> | 22 | <i class="iconfont icon-more1" @click="onMore"></i> |
23 | </div> | 23 | </div> |
24 | </div> | 24 | </div> |
25 | - <ArticleDetailCommentList ref="commentList" v-if="data.articleId" :article-id="data.articleId" :share="share" :comment-count="articleState.commentCount" :has-comment="data.hasComment"></ArticleDetailCommentList> | 25 | + <ArticleDetailCommentList ref="commentList" v-if="data.articleId" :article-id="data.articleId" :share="share" :comment-count="articleState.commentCount" :has-comment="data.hasComment" :authorUid="data.authorUid"></ArticleDetailCommentList> |
26 | </div> | 26 | </div> |
27 | 27 | ||
28 | <div v-if="listTitle" class="rec-article-title"> | 28 | <div v-if="listTitle" class="rec-article-title"> |
@@ -14,6 +14,9 @@ | @@ -14,6 +14,9 @@ | ||
14 | :share="share" | 14 | :share="share" |
15 | :pos-id="0" | 15 | :pos-id="0" |
16 | :article-id="articleId" | 16 | :article-id="articleId" |
17 | + :authorUid="authorUid" | ||
18 | + :commentUid="comment.parentComment.uid" | ||
19 | + @remove-comment="onRemoveComment" | ||
17 | @on-reply="onReply"> | 20 | @on-reply="onReply"> |
18 | </CommentItem> | 21 | </CommentItem> |
19 | </div> | 22 | </div> |
@@ -30,11 +33,11 @@ | @@ -30,11 +33,11 @@ | ||
30 | </template> | 33 | </template> |
31 | 34 | ||
32 | <script> | 35 | <script> |
33 | -import {get, forEach, find} from 'lodash'; | ||
34 | -import {Loading} from 'cube-ui'; | ||
35 | -import {mapState as mapYohoState, mapActions as mapYohoActions, createNamespacedHelpers} from 'vuex'; | 36 | +import { get, forEach, find, findIndex } from 'lodash'; |
37 | +import { Loading } from 'cube-ui'; | ||
38 | +import { mapState as mapYohoState, mapActions as mapYohoActions, createNamespacedHelpers } from 'vuex'; | ||
36 | 39 | ||
37 | -const {mapActions} = createNamespacedHelpers('comment'); | 40 | +const { mapActions } = createNamespacedHelpers('comment'); |
38 | 41 | ||
39 | export default { | 42 | export default { |
40 | name: 'ArticleDetailCommentList', | 43 | name: 'ArticleDetailCommentList', |
@@ -46,7 +49,8 @@ export default { | @@ -46,7 +49,8 @@ export default { | ||
46 | default: 1001 | 49 | default: 1001 |
47 | }, | 50 | }, |
48 | share: Boolean, | 51 | share: Boolean, |
49 | - hasComment: Boolean | 52 | + hasComment: Boolean, |
53 | + authorUid: Number | ||
50 | }, | 54 | }, |
51 | data() { | 55 | data() { |
52 | return { | 56 | return { |
@@ -128,29 +132,50 @@ export default { | @@ -128,29 +132,50 @@ export default { | ||
128 | this.onFetching = false; | 132 | this.onFetching = false; |
129 | }, this.page > 1 ? 800 : 0); | 133 | }, this.page > 1 ? 800 : 0); |
130 | }, | 134 | }, |
131 | - onReply({comment}) { | 135 | + async onReply({ comment }) { |
136 | + const uid = (await this.$sdk.getUser()).uid; | ||
137 | + | ||
132 | forEach(this.commentList, (val) => { | 138 | forEach(this.commentList, (val) => { |
133 | - if (val.parentComment && +val.parentComment.id === +comment.parentId) { | 139 | + if (val.parentComment && +val.parentComment.id === +comment.rootId) { |
134 | val.childrenComments.unshift(Object.assign(comment, { | 140 | val.childrenComments.unshift(Object.assign(comment, { |
135 | id: comment.destId, | 141 | id: comment.destId, |
136 | destId: this.articleId, | 142 | destId: this.articleId, |
137 | headIco: this.yoho.context.userHeadIco, | 143 | headIco: this.yoho.context.userHeadIco, |
138 | userName: this.yoho.context.userName, | 144 | userName: this.yoho.context.userName, |
139 | - parentUserName: get(find(val.childrenComments, {id: comment.parentId}), 'userName', '') | 145 | + uid, |
146 | + parentUserName: +val.parentComment.id === +comment.parentId ? | ||
147 | + val.parentComment.userName : | ||
148 | + get(find(val.childrenComments, { id: +comment.parentId }), 'userName', '') | ||
140 | })); | 149 | })); |
141 | } | 150 | } |
142 | }); | 151 | }); |
143 | }, | 152 | }, |
144 | - addComment(comment) { | 153 | + async addComment(comment) { |
145 | this.commentList.unshift({ | 154 | this.commentList.unshift({ |
146 | childrenComments: [], | 155 | childrenComments: [], |
147 | parentComment: Object.assign(comment, { | 156 | parentComment: Object.assign(comment, { |
148 | id: comment.destId, | 157 | id: comment.destId, |
149 | destId: this.articleId, | 158 | destId: this.articleId, |
150 | headIco: this.yoho.context.userHeadIco, | 159 | headIco: this.yoho.context.userHeadIco, |
151 | - userName: this.yoho.context.userName | 160 | + userName: this.yoho.context.userName, |
161 | + uid: (await this.$sdk.getUser()).uid | ||
152 | }) | 162 | }) |
153 | }); | 163 | }); |
164 | + }, | ||
165 | + onRemoveComment({ commentId }) { | ||
166 | + for (let [index, val] of Object.entries(this.commentList)) { | ||
167 | + if (val.parentComment && +val.parentComment.id === +commentId) { | ||
168 | + this.commentList.splice(index, 1); | ||
169 | + break; | ||
170 | + } | ||
171 | + | ||
172 | + const childrenIndex = findIndex(val.childrenComments, { id: +commentId }); | ||
173 | + | ||
174 | + if ((+index !== -1) && (childrenIndex !== -1)) { | ||
175 | + this.commentList[index].childrenComments.splice(childrenIndex, 1); | ||
176 | + break; | ||
177 | + } | ||
178 | + } | ||
154 | } | 179 | } |
155 | }, | 180 | }, |
156 | components: { | 181 | components: { |
1 | <template> | 1 | <template> |
2 | - <a class="openapp-btn hover-opacity" href="javascript:;" @click="toDownloadPage"> | 2 | + <a v-if="visible" class="openapp-btn hover-opacity" href="javascript:;" @click="toDownloadPage"> |
3 | <span class="avatar-block"> | 3 | <span class="avatar-block"> |
4 | <div class="avatar"></div> | 4 | <div class="avatar"></div> |
5 | </span> | 5 | </span> |
@@ -10,9 +10,25 @@ | @@ -10,9 +10,25 @@ | ||
10 | 10 | ||
11 | <script> | 11 | <script> |
12 | export default { | 12 | export default { |
13 | + data() { | ||
14 | + return { | ||
15 | + visible: true | ||
16 | + }; | ||
17 | + }, | ||
18 | + async mounted() { | ||
19 | + let isHide = await this.isDownloadBarHide(); | ||
20 | + | ||
21 | + if (isHide) { | ||
22 | + this.visible = false; | ||
23 | + } | ||
24 | + }, | ||
13 | methods: { | 25 | methods: { |
14 | toDownloadPage() { | 26 | toDownloadPage() { |
15 | - this.$openApp(); | 27 | + if (this.$yoho.isAndroid && (this.$yoho.isWechat || this.$yoho.isMobileQQ)) { |
28 | + this.openByBrowser(); | ||
29 | + } else { | ||
30 | + this.$openApp(); | ||
31 | + } | ||
16 | } | 32 | } |
17 | } | 33 | } |
18 | }; | 34 | }; |
@@ -11,11 +11,18 @@ export default { | @@ -11,11 +11,18 @@ export default { | ||
11 | visible: true | 11 | visible: true |
12 | }; | 12 | }; |
13 | }, | 13 | }, |
14 | - mounted() { | 14 | + async mounted() { |
15 | + const isHide = await this.isDownloadBarHide(); | ||
16 | + | ||
17 | + if (isHide) { | ||
18 | + this.visible = false; | ||
19 | + return; | ||
20 | + } | ||
21 | + | ||
15 | this.getDownloadElem((elem) => { | 22 | this.getDownloadElem((elem) => { |
16 | const newElem = this.handleElem(elem.cloneNode(true)); | 23 | const newElem = this.handleElem(elem.cloneNode(true)); |
17 | 24 | ||
18 | - // elem.parentNode.removeChild(elem); | 25 | + elem.parentNode.removeChild(elem); |
19 | this.$el.appendChild(newElem); | 26 | this.$el.appendChild(newElem); |
20 | }); | 27 | }); |
21 | }, | 28 | }, |
@@ -34,6 +41,13 @@ export default { | @@ -34,6 +41,13 @@ export default { | ||
34 | 41 | ||
35 | checkForDownload(); | 42 | checkForDownload(); |
36 | }, | 43 | }, |
44 | + openApp() { | ||
45 | + if (this.$yoho.isAndroid && (this.$yoho.isWechat || this.$yoho.isMobileQQ)) { | ||
46 | + this.openByBrowser(); | ||
47 | + } else { | ||
48 | + this.$openApp(); | ||
49 | + } | ||
50 | + }, | ||
37 | handleElem(elem) { | 51 | handleElem(elem) { |
38 | const vm = this; | 52 | const vm = this; |
39 | const miniElem = elem.querySelector('#mini-app-open'); | 53 | const miniElem = elem.querySelector('#mini-app-open'); |
@@ -54,7 +68,7 @@ export default { | @@ -54,7 +68,7 @@ export default { | ||
54 | } | 68 | } |
55 | case 'download-go': { | 69 | case 'download-go': { |
56 | // 尝试打开app | 70 | // 尝试打开app |
57 | - vm.$openApp(); | 71 | + vm.openApp(); |
58 | 72 | ||
59 | e.stopPropagation(); | 73 | e.stopPropagation(); |
60 | e.preventDefault(); | 74 | e.preventDefault(); |
@@ -62,7 +76,7 @@ export default { | @@ -62,7 +76,7 @@ export default { | ||
62 | } | 76 | } |
63 | case 'download-go-wechat': { | 77 | case 'download-go-wechat': { |
64 | // 尝试打开app | 78 | // 尝试打开app |
65 | - vm.$openApp(); | 79 | + vm.openApp(); |
66 | 80 | ||
67 | e.stopPropagation(); | 81 | e.stopPropagation(); |
68 | e.preventDefault(); | 82 | e.preventDefault(); |
@@ -113,7 +113,6 @@ export default { | @@ -113,7 +113,6 @@ export default { | ||
113 | } | 113 | } |
114 | }, | 114 | }, |
115 | mounted() { | 115 | mounted() { |
116 | - | ||
117 | this.share = !this.$yoho.isApp; | 116 | this.share = !this.$yoho.isApp; |
118 | 117 | ||
119 | this.scrollEvent = throttle(this.onDounceScroll.bind(this), throttleTime); | 118 | this.scrollEvent = throttle(this.onDounceScroll.bind(this), throttleTime); |
1 | import Article from './article'; | 1 | import Article from './article'; |
2 | import Common from './common'; | 2 | import Common from './common'; |
3 | import UserPage from './userpage'; | 3 | import UserPage from './userpage'; |
4 | +import OpenApp from './openapp'; | ||
4 | 5 | ||
5 | -export default [...Article, ...UserPage, ...Common]; | 6 | +export default [...Article, ...UserPage, ...Common, ...OpenApp]; |
apps/pages/openapp/index.js
0 → 100644
apps/pages/openapp/openapp.vue
0 → 100644
1 | +<template> | ||
2 | +<div class="bg" v-if="image"> | ||
3 | + <div class="guide"></div> | ||
4 | + <a class="btn" href="http://a.app.qq.com/o/simple.jsp?pkgname=com.yoho&g_f=995445"></a> | ||
5 | +</div> | ||
6 | +</template> | ||
7 | + | ||
8 | +<script> | ||
9 | +export default { | ||
10 | + name: 'openByBrowser', | ||
11 | + title: 'Yoho!Buy有货|年轻人潮流购物中心 ', | ||
12 | + mounted() { | ||
13 | + if (!(this.$yoho.isWechat || this.$yoho.isMobileQQ)) { | ||
14 | + this.$nextTick().then(() => { | ||
15 | + this.$openApp(); | ||
16 | + }); | ||
17 | + } | ||
18 | + }, | ||
19 | + computed: { | ||
20 | + image() { | ||
21 | + return this.$yoho.isWechat || this.$yoho.isMobileQQ; | ||
22 | + } | ||
23 | + } | ||
24 | +}; | ||
25 | +</script> | ||
26 | + | ||
27 | +<style lang="scss" scoped> | ||
28 | +.bg { | ||
29 | + background-color: white; | ||
30 | + width: 100%; | ||
31 | + height: 100%; | ||
32 | + overflow: hidden; | ||
33 | + position: absolute; | ||
34 | + top: 0; | ||
35 | + left: 0; | ||
36 | + right: 0; | ||
37 | + bottom: 0; | ||
38 | +} | ||
39 | + | ||
40 | +.guide { | ||
41 | + width: 610px; | ||
42 | + height: 852px; | ||
43 | + margin: 50px 60px 0 92px; | ||
44 | + background-image: url("~statics/image/openapp/guide.png"); | ||
45 | + background-size: cover; | ||
46 | +} | ||
47 | + | ||
48 | +.btn { | ||
49 | + display: block; | ||
50 | + width: 440px; | ||
51 | + height: 88px; | ||
52 | + margin-left: 92px; | ||
53 | + margin-top: 30px; | ||
54 | + background-image: url("~statics/image/openapp/download.png"); | ||
55 | + background-size: cover; | ||
56 | +} | ||
57 | +</style> |
1 | <template> | 1 | <template> |
2 | <Layout class="author-fans-page"> | 2 | <Layout class="author-fans-page"> |
3 | <LayoutHeader slot='header' :hide="noHeader" theme="white" class="author-page-header" :title="(isMine ? '我' : 'TA') + '的粉丝'"></LayoutHeader> | 3 | <LayoutHeader slot='header' :hide="noHeader" theme="white" class="author-page-header" :title="(isMine ? '我' : 'TA') + '的粉丝'"></LayoutHeader> |
4 | - <UserList ref="userList" :follow-name="isMine ? '回粉' : '关注'" :on-fetch="onFetch"></UserList> | 4 | + <UserList ref="userList" type="fans" :follow-name="isMine ? '回粉' : '关注'" :on-fetch="onFetch"></UserList> |
5 | </Layout> | 5 | </Layout> |
6 | </template> | 6 | </template> |
7 | 7 |
@@ -5,7 +5,7 @@ | @@ -5,7 +5,7 @@ | ||
5 | <TabBlock @on-change-tab="onChangeTab"></TabBlock> | 5 | <TabBlock @on-change-tab="onChangeTab"></TabBlock> |
6 | </template> | 6 | </template> |
7 | </LayoutHeader> | 7 | </LayoutHeader> |
8 | - <UserList ref="userList" :on-fetch="onFetch"> | 8 | + <UserList ref="userList" type="follow" :on-fetch="onFetch"> |
9 | <template v-if="activeType == 0" #item="{ data }"> | 9 | <template v-if="activeType == 0" #item="{ data }"> |
10 | <TopicItem :data="data"></TopicItem> | 10 | <TopicItem :data="data"></TopicItem> |
11 | </template> | 11 | </template> |
@@ -165,7 +165,7 @@ export default { | @@ -165,7 +165,7 @@ export default { | ||
165 | return this.authorStates[`${this.authorInfo.authorUid}-${this.authorInfo.authorType}`] || this.authorBaseData; | 165 | return this.authorStates[`${this.authorInfo.authorUid}-${this.authorInfo.authorType}`] || this.authorBaseData; |
166 | }, | 166 | }, |
167 | isAttention() { | 167 | isAttention() { |
168 | - return this.authorState.hasAttention === 'Y'; | 168 | + return this.authorState.hasAttention; |
169 | }, | 169 | }, |
170 | list() { | 170 | list() { |
171 | if (this.activeIndex === 0) { | 171 | if (this.activeIndex === 0) { |
@@ -12,7 +12,8 @@ | @@ -12,7 +12,8 @@ | ||
12 | <div v-for="(item, index) in list" :key="index" class="item"> | 12 | <div v-for="(item, index) in list" :key="index" class="item"> |
13 | <slot name="item" :data="item"> | 13 | <slot name="item" :data="item"> |
14 | <div class="user-item"> | 14 | <div class="user-item"> |
15 | - <WidgetAvatar class="head-ico" :src="item.headIcon" :group="item.authGroupId" :width="100" :height="100" @click.native="toUserPage(item)"></WidgetAvatar> | 15 | + <WidgetAvatar class="head-ico" :src="item.headIcon" :group="item.authGroupId" :width="100" :height="100" |
16 | + @click.native="toUserPage(item)"></WidgetAvatar> | ||
16 | <div class="user-info" @click="toUserPage(item)"> | 17 | <div class="user-info" @click="toUserPage(item)"> |
17 | <p class="name">{{item.nickName}}</p> | 18 | <p class="name">{{item.nickName}}</p> |
18 | <p v-if="item.articleCount || item.fansCount" class="extra"> | 19 | <p v-if="item.articleCount || item.fansCount" class="extra"> |
@@ -20,9 +21,18 @@ | @@ -20,9 +21,18 @@ | ||
20 | <span v-if="item.fansCount">粉丝·{{item.fansCount}}</span> | 21 | <span v-if="item.fansCount">粉丝·{{item.fansCount}}</span> |
21 | </p> | 22 | </p> |
22 | </div> | 23 | </div> |
23 | - <div class="option-btn" :class="{'follow': item.isAttention}"> | ||
24 | - <WidgetFollow class="click-wrap" :author-uid="item.userId" :author-type="item.userType" :follow="item.isAttention" @on-follow="follow => onFollow(follow, index)"></WidgetFollow> | ||
25 | - {{item.isAttention ? '已关注' : followName}} | 24 | + <div class="option-btn" :class="{'follow': item.isAttention === 'Y', 'rm-padding': item.isAttention === 'O'}"> |
25 | + <WidgetFollow class="click-wrap" :author-uid="item.userId" :author-type="item.userType" | ||
26 | + :follow="item.isAttention" @on-follow="follow => onFollow(follow, index)"></WidgetFollow> | ||
27 | + <template v-if="item.isAttention === 'Y'"> | ||
28 | + {{'已关注'}} | ||
29 | + </template> | ||
30 | + <template v-else-if="item.isAttention === 'N'"> | ||
31 | + {{'关注'}} | ||
32 | + </template> | ||
33 | + <template v-else-if="item.isAttention === 'O'"> | ||
34 | + <div class="each-follow"></div> | ||
35 | + </template> | ||
26 | </div> | 36 | </div> |
27 | </div> | 37 | </div> |
28 | </slot> | 38 | </slot> |
@@ -36,8 +46,8 @@ | @@ -36,8 +46,8 @@ | ||
36 | </template> | 46 | </template> |
37 | 47 | ||
38 | <script> | 48 | <script> |
39 | -import {get} from 'lodash'; | ||
40 | -import {Scroll, Loading} from 'cube-ui'; | 49 | +import { get } from 'lodash'; |
50 | +import { Scroll, Loading } from 'cube-ui'; | ||
41 | 51 | ||
42 | export default { | 52 | export default { |
43 | props: { | 53 | props: { |
@@ -48,7 +58,8 @@ export default { | @@ -48,7 +58,8 @@ export default { | ||
48 | onFetch: { | 58 | onFetch: { |
49 | type: Function, | 59 | type: Function, |
50 | required: true | 60 | required: true |
51 | - } | 61 | + }, |
62 | + type: String | ||
52 | }, | 63 | }, |
53 | data() { | 64 | data() { |
54 | return { | 65 | return { |
@@ -100,7 +111,7 @@ export default { | @@ -100,7 +111,7 @@ export default { | ||
100 | } | 111 | } |
101 | 112 | ||
102 | list.forEach(val => { | 113 | list.forEach(val => { |
103 | - val.isAttention = val.hasAttention === 'Y'; | 114 | + val.isAttention = val.hasAttention; |
104 | }); | 115 | }); |
105 | 116 | ||
106 | this.list = this.list.concat(list); | 117 | this.list = this.list.concat(list); |
@@ -118,7 +129,17 @@ export default { | @@ -118,7 +129,17 @@ export default { | ||
118 | }); | 129 | }); |
119 | }, | 130 | }, |
120 | onFollow(follow, index) { | 131 | onFollow(follow, index) { |
121 | - this.list[index].isAttention = follow; | 132 | + |
133 | + if (this.type === 'fans') { | ||
134 | + // 粉丝是已关注的列表,你关注他,就变成互相关注 | ||
135 | + if (follow === 'Y') { | ||
136 | + this.list[index].isAttention = 'O'; | ||
137 | + } else { | ||
138 | + this.list[index].isAttention = follow; | ||
139 | + } | ||
140 | + } else { | ||
141 | + this.list[index].isAttention = follow; | ||
142 | + } | ||
122 | }, | 143 | }, |
123 | toUserPage(item) { | 144 | toUserPage(item) { |
124 | this.$router.push({ | 145 | this.$router.push({ |
@@ -178,6 +199,11 @@ export default { | @@ -178,6 +199,11 @@ export default { | ||
178 | border-color: #b0b0b0; | 199 | border-color: #b0b0b0; |
179 | } | 200 | } |
180 | 201 | ||
202 | + &.rm-padding { | ||
203 | + padding: 0; | ||
204 | + border: none; | ||
205 | + } | ||
206 | + | ||
181 | .click-wrap { | 207 | .click-wrap { |
182 | width: 140%; | 208 | width: 140%; |
183 | height: 180%; | 209 | height: 180%; |
@@ -189,6 +215,13 @@ export default { | @@ -189,6 +215,13 @@ export default { | ||
189 | font-size: 0; | 215 | font-size: 0; |
190 | opacity: 0; | 216 | opacity: 0; |
191 | } | 217 | } |
218 | + | ||
219 | + .each-follow { | ||
220 | + width: 110px; | ||
221 | + height: 50px; | ||
222 | + background-image: url("~statics/image/userpage/follow.png"); | ||
223 | + background-size: cover; | ||
224 | + } | ||
192 | } | 225 | } |
193 | } | 226 | } |
194 | 227 |
apps/statics/image/openapp/download.png
0 → 100644
12.5 KB
apps/statics/image/openapp/guide.png
0 → 100644
150 KB
apps/statics/image/userpage/follow.png
0 → 100644
2.04 KB
@@ -276,33 +276,33 @@ export default { | @@ -276,33 +276,33 @@ export default { | ||
276 | 276 | ||
277 | commit(Types.GUANG_CHANGE_PRODUCT_FAV, favsList); | 277 | commit(Types.GUANG_CHANGE_PRODUCT_FAV, favsList); |
278 | }, | 278 | }, |
279 | - async reportArticle(actions, {articleId}) { | ||
280 | - const result = await this.$api.post('/api/grass/reportIllegalArticle', {articleId}); | 279 | + async reportArticle(actions, { articleId }) { |
280 | + const result = await this.$api.post('/api/grass/reportIllegalArticle', { articleId }); | ||
281 | 281 | ||
282 | return result; | 282 | return result; |
283 | }, | 283 | }, |
284 | - async deleteArticle(actions, {articleId}) { | ||
285 | - const result = await this.$api.post('/api/grass/deleteGrassArticle', {articleId}); | 284 | + async deleteArticle(actions, { articleId }) { |
285 | + const result = await this.$api.post('/api/grass/deleteGrassArticle', { articleId }); | ||
286 | 286 | ||
287 | return result; | 287 | return result; |
288 | }, | 288 | }, |
289 | - async fetchTopicSimpleInfo({ commit, state }, {topicId, thumb}) { | 289 | + async fetchTopicSimpleInfo({ commit, state }, { topicId, thumb }) { |
290 | if (state.fetchTopicInfo) { | 290 | if (state.fetchTopicInfo) { |
291 | return Promise.resolve({}); | 291 | return Promise.resolve({}); |
292 | } | 292 | } |
293 | 293 | ||
294 | commit(Types.FETCH_TOPIC_INFO_REQUEST); | 294 | commit(Types.FETCH_TOPIC_INFO_REQUEST); |
295 | - const result = await this.$api.post('/api/grass/getGrassTopicSimpleInfo', {topicId}); | 295 | + const result = await this.$api.post('/api/grass/getGrassTopicSimpleInfo', { topicId }); |
296 | 296 | ||
297 | if (result.code === 200) { | 297 | if (result.code === 200) { |
298 | - commit(Types.FETCH_TOPIC_INFO_SUCCESS, {topicId, data: result.data, thumb}); | 298 | + commit(Types.FETCH_TOPIC_INFO_SUCCESS, { topicId, data: result.data, thumb }); |
299 | } else { | 299 | } else { |
300 | commit(Types.FETCH_TOPIC_INFO_FAILD, {}); | 300 | commit(Types.FETCH_TOPIC_INFO_FAILD, {}); |
301 | } | 301 | } |
302 | 302 | ||
303 | return result; | 303 | return result; |
304 | }, | 304 | }, |
305 | - async fetchTopicRelatedArticles({ commit, state }, {topicId, page, type}) { | 305 | + async fetchTopicRelatedArticles({ commit, state }, { topicId, page, type }) { |
306 | commit(Types.FETCH_ARTICLE_TOPIC_REQUEST, { page }); | 306 | commit(Types.FETCH_ARTICLE_TOPIC_REQUEST, { page }); |
307 | const result = await this.$api.post('/api/grass/topicRelatedArticles', { | 307 | const result = await this.$api.post('/api/grass/topicRelatedArticles', { |
308 | topicId, | 308 | topicId, |
@@ -342,7 +342,7 @@ export default { | @@ -342,7 +342,7 @@ export default { | ||
342 | 342 | ||
343 | return result; | 343 | return result; |
344 | }, | 344 | }, |
345 | - async fetchFindNiceGoodsArticles({ commit, state }, { page, limit, thumb}) { | 345 | + async fetchFindNiceGoodsArticles({ commit, state }, { page, limit, thumb }) { |
346 | commit(Types.FETCH_NICE_GOODS_REQUEST, { page }); | 346 | commit(Types.FETCH_NICE_GOODS_REQUEST, { page }); |
347 | const result = await this.$api.post('/api/grass/findGoodsList', { | 347 | const result = await this.$api.post('/api/grass/findGoodsList', { |
348 | page, | 348 | page, |
@@ -365,7 +365,7 @@ export default { | @@ -365,7 +365,7 @@ export default { | ||
365 | 365 | ||
366 | return result; | 366 | return result; |
367 | }, | 367 | }, |
368 | - async fetchTopicList({ commit, state }, {page, limit}) { | 368 | + async fetchTopicList({ commit, state }, { page, limit }) { |
369 | if (state.fetchTopicList) { | 369 | if (state.fetchTopicList) { |
370 | return {}; | 370 | return {}; |
371 | } | 371 | } |
@@ -391,5 +391,17 @@ export default { | @@ -391,5 +391,17 @@ export default { | ||
391 | } | 391 | } |
392 | 392 | ||
393 | return result; | 393 | return result; |
394 | - } | 394 | + }, |
395 | + | ||
396 | + async fetchProductBySknList(ctx, { productSknList }) { | ||
397 | + const productSkn = productSknList.join(','); | ||
398 | + | ||
399 | + const result = await this.$api.post('/api/grass/product', { | ||
400 | + productSkn | ||
401 | + }); | ||
402 | + | ||
403 | + return get(result, 'data.product_list', []); | ||
404 | + }, | ||
405 | + | ||
406 | + | ||
395 | }; | 407 | }; |
@@ -212,6 +212,14 @@ export default { | @@ -212,6 +212,14 @@ export default { | ||
212 | updateArticleState(state, article); | 212 | updateArticleState(state, article); |
213 | } | 213 | } |
214 | }, | 214 | }, |
215 | + [Types.SUB_ARTICLE_COMMENT_COUNT](state, {articleId, subCount}) { | ||
216 | + let article = state.articleStates[articleId]; | ||
217 | + | ||
218 | + if (article) { | ||
219 | + article.commentCount = subCount ? (article.commentCount - subCount) : (articleId.commentCount - 1); | ||
220 | + updateArticleState(state, article); | ||
221 | + } | ||
222 | + }, | ||
215 | [Types.ASYNC_ARTICLE_COMMENT](state, {articleId, type}) { | 223 | [Types.ASYNC_ARTICLE_COMMENT](state, {articleId, type}) { |
216 | state[articlefield(type)].forEach(article => { | 224 | state[articlefield(type)].forEach(article => { |
217 | if (article.articleId === articleId) { | 225 | if (article.articleId === articleId) { |
@@ -26,6 +26,7 @@ export const CHANGE_ARTICLE_LIST_SLIDE = 'CHANGE_ARTICLE_LIST_SLIDE'; | @@ -26,6 +26,7 @@ export const CHANGE_ARTICLE_LIST_SLIDE = 'CHANGE_ARTICLE_LIST_SLIDE'; | ||
26 | 26 | ||
27 | export const UPDATE_ARTICLE_STATE = 'UPDATE_ARTICLE_STATE'; | 27 | export const UPDATE_ARTICLE_STATE = 'UPDATE_ARTICLE_STATE'; |
28 | export const UPDATE_ARTICLE_COMMENT_COUNT = 'UPDATE_ARTICLE_COMMENT_COUNT'; | 28 | export const UPDATE_ARTICLE_COMMENT_COUNT = 'UPDATE_ARTICLE_COMMENT_COUNT'; |
29 | +export const SUB_ARTICLE_COMMENT_COUNT = 'SUB_ARTICLE_COMMENT_COUNT'; | ||
29 | export const ASYNC_ARTICLE_COMMENT = 'ASYNC_ARTICLE_COMMENT'; | 30 | export const ASYNC_ARTICLE_COMMENT = 'ASYNC_ARTICLE_COMMENT'; |
30 | export const CHANGE_ARTICLE_LIST_INTRO = 'CHANGE_ARTICLE_LIST_INTRO'; | 31 | export const CHANGE_ARTICLE_LIST_INTRO = 'CHANGE_ARTICLE_LIST_INTRO'; |
31 | export const CHANGE_ARTICLE_LIST_INTRO_HEIGHT = 'CHANGE_ARTICLE_LIST_INTRO_HEIGHT'; | 32 | export const CHANGE_ARTICLE_LIST_INTRO_HEIGHT = 'CHANGE_ARTICLE_LIST_INTRO_HEIGHT'; |
@@ -69,5 +69,17 @@ export default { | @@ -69,5 +69,17 @@ export default { | ||
69 | }); | 69 | }); |
70 | 70 | ||
71 | return result; | 71 | return result; |
72 | + }, | ||
73 | + | ||
74 | + async setCommentStatus(ctx, {type, commentId}) { | ||
75 | + if (type === 1) { | ||
76 | + return this.$api.post('/api/grass/deleteComment', { | ||
77 | + commentId | ||
78 | + }); | ||
79 | + } else if (type === 2) { | ||
80 | + return this.$api.post('/api/grass/reportComment', { | ||
81 | + commentId | ||
82 | + }); | ||
83 | + } | ||
72 | } | 84 | } |
73 | }; | 85 | }; |
1 | -import {get, first} from 'lodash'; | 1 | +import { get, first } from 'lodash'; |
2 | 2 | ||
3 | -const DEFAULT_SHARE_IMAGE = 'http://static.yohobuy.com/m/v1/img/touch/apple-touch-icon-144x144-precomposed-new.png'; | 3 | +function _version2num(version) { |
4 | + if (!version) { | ||
5 | + return 0; | ||
6 | + } | ||
7 | + | ||
8 | + let [m, j, b] = version.split(','); | ||
9 | + | ||
10 | + return +m * 10000 + +j * 100 + +b; | ||
11 | +} | ||
12 | + | ||
13 | +function versionCompare(left, right) { | ||
14 | + let leftNum = _version2num(left); | ||
15 | + let rightNum = _version2num(right); | ||
16 | + | ||
17 | + if (leftNum === rightNum) { | ||
18 | + return 0; | ||
19 | + } else if (leftNum > rightNum) { | ||
20 | + return 1; | ||
21 | + } else { | ||
22 | + return -1; | ||
23 | + } | ||
24 | +} | ||
25 | + | ||
26 | +const DEFAULT_SHARE_IMAGE = | ||
27 | + 'http://static.yohobuy.com/m/v1/img/touch/apple-touch-icon-144x144-precomposed-new.png'; | ||
4 | 28 | ||
5 | function handleProtocol(url) { | 29 | function handleProtocol(url) { |
6 | if (url.indexOf('//') < 0 || url.indexOf('http') >= 0) { | 30 | if (url.indexOf('//') < 0 || url.indexOf('http') >= 0) { |
@@ -13,7 +37,7 @@ function handleProtocol(url) { | @@ -13,7 +37,7 @@ function handleProtocol(url) { | ||
13 | return url.join('//'); | 37 | return url.join('//'); |
14 | } | 38 | } |
15 | 39 | ||
16 | -const getDetailShareData = (article) => { | 40 | +const getDetailShareData = (article, app_version = '6.9.11') => { |
17 | let shareImage = ''; | 41 | let shareImage = ''; |
18 | 42 | ||
19 | let desc = ''; | 43 | let desc = ''; |
@@ -27,45 +51,76 @@ const getDetailShareData = (article) => { | @@ -27,45 +51,76 @@ const getDetailShareData = (article) => { | ||
27 | } else { | 51 | } else { |
28 | let blockList = get(article, 'blockList', []); | 52 | let blockList = get(article, 'blockList', []); |
29 | 53 | ||
30 | - shareImage = get(first(blockList.filter(block => block.templateKey === 'image')), 'contentData', ''); | ||
31 | - desc = get(blockList.filter(block => block.templateKey === 'text'), '[0].contentData', ''); | 54 | + shareImage = get( |
55 | + first(blockList.filter(block => block.templateKey === 'image')), | ||
56 | + 'contentData', | ||
57 | + '', | ||
58 | + ); | ||
59 | + desc = get( | ||
60 | + blockList.filter(block => block.templateKey === 'text'), | ||
61 | + '[0].contentData', | ||
62 | + '', | ||
63 | + ); | ||
32 | } | 64 | } |
33 | 65 | ||
34 | if (shareImage && shareImage.indexOf('//') >= 0) { | 66 | if (shareImage && shareImage.indexOf('//') >= 0) { |
35 | - shareImage = `${window ? window.location.protocol : ''}//${shareImage.split('//')[1]}`; | 67 | + shareImage = `${window ? window.location.protocol : ''}//${ |
68 | + shareImage.split('//')[1] | ||
69 | + }`; | ||
36 | } | 70 | } |
37 | 71 | ||
72 | + const requiredVersion = '6.9.11'; | ||
73 | + | ||
74 | + // let hideType = ['7', '8', '9']; | ||
75 | + let hideType = ['8', '9']; | ||
76 | + | ||
77 | + // if (versionCompare(app_version, requiredVersion) >= 0) { | ||
78 | + // hideType = ['8', '9']; | ||
79 | + // } | ||
80 | + | ||
38 | return { | 81 | return { |
39 | title: `@${article.authorName} 在有货社区上发了一篇内容,快点开看看!`, | 82 | title: `@${article.authorName} 在有货社区上发了一篇内容,快点开看看!`, |
40 | - imgUrl: handleProtocol(get(shareImage.split('?'), '[0]') || DEFAULT_SHARE_IMAGE), | ||
41 | - link: handleProtocol(`${window ? window.location.origin : ''}/grass/article/${article.articleId}?share=true`), | 83 | + imgUrl: handleProtocol( |
84 | + get(shareImage.split('?'), '[0]') || DEFAULT_SHARE_IMAGE, | ||
85 | + ), | ||
86 | + link: handleProtocol( | ||
87 | + `${window ? window.location.origin : ''}/grass/article/${ | ||
88 | + article.articleId | ||
89 | + }?share=true`, | ||
90 | + ), | ||
42 | desc, | 91 | desc, |
43 | - hideType: ['7', '8', '9'] | 92 | + hideType, |
93 | + shareType: 'grassDetail', | ||
94 | + userName: article.authorName, | ||
95 | + userIcon: article.authorHeadIco, | ||
96 | + articleId: article.articleId, | ||
44 | }; | 97 | }; |
45 | }; | 98 | }; |
46 | 99 | ||
47 | -const getTopicShareData = (topic) => { | 100 | +const getTopicShareData = topic => { |
48 | return { | 101 | return { |
49 | title: topic.topicName, | 102 | title: topic.topicName, |
50 | imgUrl: handleProtocol(topic.topicImageUrl), | 103 | imgUrl: handleProtocol(topic.topicImageUrl), |
51 | - link: handleProtocol(`${location.origin}/grass/topic/${topic.topicId}?share=true`), | 104 | + link: handleProtocol( |
105 | + `${location.origin}/grass/topic/${topic.topicId}?share=true`, | ||
106 | + ), | ||
52 | desc: '我在有货的社区发现一个热门话题。' + topic.topicDesc, | 107 | desc: '我在有货的社区发现一个热门话题。' + topic.topicDesc, |
53 | - hideType: ['7', '8', '9'] | 108 | + hideType: ['7', '8', '9'], |
54 | }; | 109 | }; |
55 | }; | 110 | }; |
56 | 111 | ||
57 | -const getAuthorShareData = (author) => { | 112 | +const getAuthorShareData = author => { |
58 | return { | 113 | return { |
59 | title: `@${author.nickName} 在YO!社区,一起来玩潮流!`, | 114 | title: `@${author.nickName} 在YO!社区,一起来玩潮流!`, |
60 | - imgUrl: handleProtocol(get(author, 'headIco', '').split('?')[0] || DEFAULT_SHARE_IMAGE), | ||
61 | - link: handleProtocol(`${location.origin}/grass/author/${author.authorType}/${author.authorUid}?share=true`), | 115 | + imgUrl: handleProtocol( |
116 | + get(author, 'headIco', '').split('?')[0] || DEFAULT_SHARE_IMAGE, | ||
117 | + ), | ||
118 | + link: handleProtocol( | ||
119 | + `${location.origin}/grass/author/${author.authorType}/${author.authorUid}?share=true`, | ||
120 | + ), | ||
62 | desc: author.signature || '', | 121 | desc: author.signature || '', |
63 | - hideType: ['7', '8', '9'] | 122 | + hideType: ['7', '8', '9'], |
64 | }; | 123 | }; |
65 | }; | 124 | }; |
66 | 125 | ||
67 | -export { | ||
68 | - getDetailShareData, | ||
69 | - getTopicShareData, | ||
70 | - getAuthorShareData | ||
71 | -}; | 126 | +export { getDetailShareData, getTopicShareData, getAuthorShareData }; |
@@ -275,5 +275,24 @@ module.exports = { | @@ -275,5 +275,24 @@ module.exports = { | ||
275 | params: { | 275 | params: { |
276 | articleId: {type: Number} | 276 | articleId: {type: Number} |
277 | } | 277 | } |
278 | + }, | ||
279 | + '/api/grass/product': { | ||
280 | + api: 'h5.product.batch', | ||
281 | + params: { | ||
282 | + productSkn: {type: String} | ||
283 | + } | ||
284 | + }, | ||
285 | + '/api/grass/reportComment': { | ||
286 | + api: 'app.grass.reportIllegalArticle', | ||
287 | + params: { | ||
288 | + commentId: {type: Number} | ||
289 | + } | ||
290 | + }, | ||
291 | + '/api/grass/deleteComment': { | ||
292 | + api: 'app.grass.delArticleComment', | ||
293 | + auth: true, | ||
294 | + params: { | ||
295 | + commentId: {type: Number} | ||
296 | + } | ||
278 | } | 297 | } |
279 | }; | 298 | }; |
@@ -67,7 +67,8 @@ const getContext = (req) => { | @@ -67,7 +67,8 @@ const getContext = (req) => { | ||
67 | isWeibo: req.yoho.isWeibo, | 67 | isWeibo: req.yoho.isWeibo, |
68 | isYohoBuy: req.yoho.isYohoApp, | 68 | isYohoBuy: req.yoho.isYohoApp, |
69 | isChat: req.yoho.isChat, | 69 | isChat: req.yoho.isChat, |
70 | - clientIp: req.yoho.clientIp, | 70 | + isMiniApp: req.yoho.isMiniApp, |
71 | + clientIp: req.yoho.clientIp | ||
71 | }, | 72 | }, |
72 | ua: req.get('user-agent'), | 73 | ua: req.get('user-agent'), |
73 | hostname: os.hostname(), | 74 | hostname: os.hostname(), |
@@ -14,6 +14,7 @@ | @@ -14,6 +14,7 @@ | ||
14 | <script type="text/javascript"> | 14 | <script type="text/javascript"> |
15 | (function(d,c){var e=d.documentElement,a="orientationchange" in window?"orientationchange":"resize",b=function(){var f=e.clientWidth;if(!f){return}if(f>=750){e.style.fontSize="40px"}else{e.style.fontSize=40*(f/750)+"px"}};if(!d.addEventListener){return}b();c.addEventListener(a,b,false);d.addEventListener("DOMContentLoaded",b,false)})(document,window); | 15 | (function(d,c){var e=d.documentElement,a="orientationchange" in window?"orientationchange":"resize",b=function(){var f=e.clientWidth;if(!f){return}if(f>=750){e.style.fontSize="40px"}else{e.style.fontSize=40*(f/750)+"px"}};if(!d.addEventListener){return}b();c.addEventListener(a,b,false);d.addEventListener("DOMContentLoaded",b,false)})(document,window); |
16 | </script> | 16 | </script> |
17 | + <script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.3.2.js"></script> | ||
17 | <link rel="dns-prefetch" href="//cdn.yoho.cn"> | 18 | <link rel="dns-prefetch" href="//cdn.yoho.cn"> |
18 | <link rel="dns-prefetch" href="imgsocial.yohobuy.com"> | 19 | <link rel="dns-prefetch" href="imgsocial.yohobuy.com"> |
19 | <link rel="dns-prefetch" href="flv01.static.yhbimg.com"> | 20 | <link rel="dns-prefetch" href="flv01.static.yhbimg.com"> |
-
Please register or login to post a comment