Authored by 陈峰

commit

@@ -18,8 +18,11 @@ export default { @@ -18,8 +18,11 @@ export default {
18 }, 18 },
19 methods: { 19 methods: {
20 ...mapActions(['postComment']), 20 ...mapActions(['postComment']),
21 - openComentInput() {  
22 - const hint = this.user ? `回复${this.user}:` : ''; 21 + async openComentInput() {
  22 + const user = await this.$sdk.getUser();
  23 +
  24 + if (user && user.uid) {
  25 + const hint = this.user ? `回复${this.user}:` : '评论:';
23 26
24 if (this.$yoho.isYohoBuy) { 27 if (this.$yoho.isYohoBuy) {
25 this.$yoho.getInput({hint}, (content) => { 28 this.$yoho.getInput({hint}, (content) => {
@@ -39,6 +42,9 @@ export default { @@ -39,6 +42,9 @@ export default {
39 } 42 }
40 }).show(); 43 }).show();
41 } 44 }
  45 + } else {
  46 + this.$sdk.goLogin();
  47 + }
42 }, 48 },
43 async comment(content) { 49 async comment(content) {
44 const result = await this.postComment({ 50 const result = await this.postComment({
  1 +export default {
  2 + name: 'AuthComponent',
  3 + props: {
  4 + tag: String,
  5 + auth: {
  6 + type: Boolean,
  7 + default: true
  8 + }
  9 + },
  10 + methods: {
  11 + async onClick() {
  12 + if (!this.auth) {
  13 + return this.$emit('click');
  14 + }
  15 + const user = await this.$sdk.getUser();
  16 +
  17 + if (user && user.uid) {
  18 + this.$emit('click', {uid: user.uid});
  19 + } else {
  20 + this.$emit('cancel');
  21 + this.$sdk.goLogin();
  22 + }
  23 + }
  24 + },
  25 + render(h) {
  26 + return h(this.tag || 'div', {
  27 + on: {
  28 + click: this.onClick.bind(this)
  29 + }
  30 + }, this.$slots.default);
  31 + }
  32 +};
@@ -2,10 +2,12 @@ import Layout from './layout'; @@ -2,10 +2,12 @@ import Layout from './layout';
2 import LayoutHeader from './layout-header'; 2 import LayoutHeader from './layout-header';
3 import LayoutRecycleList from './layout-recycle-list'; 3 import LayoutRecycleList from './layout-recycle-list';
4 import RecycleList from './recycle-list'; 4 import RecycleList from './recycle-list';
  5 +import AuthComponent from './auth-component';
5 6
6 export default [ 7 export default [
7 Layout, 8 Layout,
8 LayoutHeader, 9 LayoutHeader,
9 LayoutRecycleList, 10 LayoutRecycleList,
10 RecycleList, 11 RecycleList,
  12 + AuthComponent,
11 ]; 13 ];
@@ -10,10 +10,10 @@ @@ -10,10 +10,10 @@
10 <p class="price">¥{{product.salesPrice}}</p> 10 <p class="price">¥{{product.salesPrice}}</p>
11 </div> 11 </div>
12 </div> 12 </div>
13 - <div 13 + <AuthComponent
14 class="btn-fav hover-opacity" 14 class="btn-fav hover-opacity"
15 - @click.stop="onFav"  
16 - :class="favClass">{{favText}}</div> 15 + @click="onFav"
  16 + :class="favClass">{{favText}}</AuthComponent>
17 </div> 17 </div>
18 </template> 18 </template>
19 19
@@ -50,10 +50,6 @@ export default { @@ -50,10 +50,6 @@ export default {
50 methods: { 50 methods: {
51 ...mapActions(['postProductFav']), 51 ...mapActions(['postProductFav']),
52 async onFav() { 52 async onFav() {
53 - if (!this.auth()) {  
54 - return;  
55 - }  
56 -  
57 if (this.posting) { 53 if (this.posting) {
58 return; 54 return;
59 } 55 }
1 <template> 1 <template>
2 - <div class="btn-follow hover-opacity" :class="followClass" @click="onFollow">{{followText}}</div> 2 + <AuthComponent class="btn-follow hover-opacity" :class="followClass" @click="onFollow">{{followText}}</AuthComponent>
3 </template> 3 </template>
4 4
5 <script> 5 <script>
@@ -41,10 +41,6 @@ export default { @@ -41,10 +41,6 @@ export default {
41 methods: { 41 methods: {
42 ...mapActions(['followUser']), 42 ...mapActions(['followUser']),
43 async onFollow() { 43 async onFollow() {
44 - if (!this.auth()) {  
45 - return;  
46 - }  
47 -  
48 if (this.loading) { 44 if (this.loading) {
49 return; 45 return;
50 } 46 }
1 <template> 1 <template>
2 - <div class="icon-btn" @click="onClick" :style="btnStyle"> 2 + <AuthComponent :auth="isAuth" class="icon-btn" @click="onClick" :style="btnStyle">
3 <i class="iconfont" :class="iconClass" :style="iconStyle"></i> 3 <i class="iconfont" :class="iconClass" :style="iconStyle"></i>
4 <p v-if="viewText" class="icon-btn-text" :style="textStyle"> 4 <p v-if="viewText" class="icon-btn-text" :style="textStyle">
5 <span class="view-text">{{viewText}}</span> 5 <span class="view-text">{{viewText}}</span>
6 <span class="placeholder-text">{{placText}}</span> 6 <span class="placeholder-text">{{placText}}</span>
7 </p> 7 </p>
8 - </div> 8 + </AuthComponent>
9 </template> 9 </template>
10 10
11 <script> 11 <script>
12 - import {forEach, get, fill} from 'lodash';  
13 - import {createNamespacedHelpers} from 'vuex';  
14 - const {mapActions} = createNamespacedHelpers('user'); 12 +import {forEach, fill} from 'lodash';
  13 +import {createNamespacedHelpers} from 'vuex';
  14 +const {mapActions} = createNamespacedHelpers('user');
15 15
16 - const classMap = { 16 +const classMap = {
17 fav: { 17 fav: {
18 default: 'icon-zan', 18 default: 'icon-zan',
19 selected: 'icon-zan-fill' 19 selected: 'icon-zan-fill'
@@ -28,9 +28,9 @@ @@ -28,9 +28,9 @@
28 msg: { 28 msg: {
29 default: 'icon-msg' 29 default: 'icon-msg'
30 } 30 }
31 - }; 31 +};
32 32
33 - const defaultOption = { 33 +const defaultOption = {
34 canSelect: true, // 是否支持选中 34 canSelect: true, // 是否支持选中
35 selected: false, // 初始选中状态(不受是否支持选中控制) 35 selected: false, // 初始选中状态(不受是否支持选中控制)
36 color: '#444', // btn字体颜色 36 color: '#444', // btn字体颜色
@@ -42,9 +42,9 @@ @@ -42,9 +42,9 @@
42 textZoom: 0.9, // text缩放 42 textZoom: 0.9, // text缩放
43 textAutoChange: true, // text自动增减,只支持number类型(受是否支持选中控制) 43 textAutoChange: true, // text自动增减,只支持number类型(受是否支持选中控制)
44 emitName: '' // 点击触发事件名称 44 emitName: '' // 点击触发事件名称
45 - }; 45 +};
46 46
47 - export default { 47 +export default {
48 name: 'WidgetIconBtn', 48 name: 'WidgetIconBtn',
49 props: { 49 props: {
50 type: { 50 type: {
@@ -72,7 +72,7 @@ @@ -72,7 +72,7 @@
72 btnSelected: false, 72 btnSelected: false,
73 actionClass: '', 73 actionClass: '',
74 editText: null 74 editText: null
75 - } 75 + };
76 }, 76 },
77 created() { 77 created() {
78 forEach(defaultOption, (value, key) => { 78 forEach(defaultOption, (value, key) => {
@@ -81,6 +81,20 @@ @@ -81,6 +81,20 @@
81 this.viewOption = {...this.viewOption}; 81 this.viewOption = {...this.viewOption};
82 }, 82 },
83 computed: { 83 computed: {
  84 + syncFnName() {
  85 + if (this.articleId) {
  86 + if (this.type === 'fav') {
  87 + return 'praiseArticle';
  88 + } else if (this.type === 'star') {
  89 + return 'followArticle';
  90 + }
  91 + } else if (this.commentId && this.type === 'fav') {
  92 + return 'praiseComment';
  93 + }
  94 + },
  95 + isAuth() {
  96 + return !!this.syncFnName;
  97 + },
84 btnStyle() { 98 btnStyle() {
85 let color = this.viewOption.color || defaultOption.color; 99 let color = this.viewOption.color || defaultOption.color;
86 100
@@ -90,19 +104,17 @@ @@ -90,19 +104,17 @@
90 if (this.actionClass) { 104 if (this.actionClass) {
91 return this.actionClass; 105 return this.actionClass;
92 } 106 }
93 -  
94 - if (!this._icon) {  
95 - this._type = classMap[this.type] ? this.type : 'fav'  
96 - this._icon = classMap[this._type];  
97 - } 107 + if (classMap[this.type]) {
  108 + const currentClass = classMap[this.type];
98 109
99 if (this.viewOption.selected) { 110 if (this.viewOption.selected) {
100 this.btnSelected = true; 111 this.btnSelected = true;
101 112
102 - return this._icon.selected || this._icon.default; 113 + return currentClass.selected || currentClass.default;
103 } 114 }
104 115
105 - return this._icon.default; 116 + return currentClass.default;
  117 + }
106 }, 118 },
107 iconStyle() { 119 iconStyle() {
108 return `font-size: ${this.pxToRem(this.viewOption.iconFontSize)};`; 120 return `font-size: ${this.pxToRem(this.viewOption.iconFontSize)};`;
@@ -145,7 +157,7 @@ @@ -145,7 +157,7 @@
145 const rootValue = 40; 157 const rootValue = 40;
146 158
147 if (typeof px !== 'number') { 159 if (typeof px !== 'number') {
148 - px = parseInt(`0${px}`); 160 + px = parseInt(`0${px}`, 10);
149 } 161 }
150 162
151 if (px > 2) { 163 if (px > 2) {
@@ -158,15 +170,13 @@ @@ -158,15 +170,13 @@
158 this.btnSelected = !this.btnSelected; 170 this.btnSelected = !this.btnSelected;
159 171
160 if (this.viewOption.textAutoChange) { 172 if (this.viewOption.textAutoChange) {
161 - let _text = this.editText || this.text;  
162 -  
163 if (!isNaN(Number(this.viewText))) { 173 if (!isNaN(Number(this.viewText))) {
164 this.editText = Number(this.viewText) + (this.btnSelected ? 1 : -1); 174 this.editText = Number(this.viewText) + (this.btnSelected ? 1 : -1);
165 } 175 }
166 } 176 }
167 177
168 - if (this._icon.selected) {  
169 - this.actionClass = this.btnSelected ? this._icon.selected : this._icon.default; 178 + if (classMap[this.type]) {
  179 + this.actionClass = this.btnSelected ? classMap[this.type].selected : classMap[this.type].default;
170 } 180 }
171 }, 181 },
172 syncService(type, data) { 182 syncService(type, data) {
@@ -183,56 +193,32 @@ @@ -183,56 +193,32 @@
183 193
184 if (this.viewOption.canSelect) { 194 if (this.viewOption.canSelect) {
185 this.changeBtnStatus(); 195 this.changeBtnStatus();
186 -  
187 - let syncFnName = '';  
188 -  
189 - if (this.articleId) {  
190 - if (this._type === 'fav') {  
191 - syncFnName = 'praiseArticle';  
192 - } else if (this._type === 'star') {  
193 - syncFnName = 'followArticle';  
194 - }  
195 - } else if (this.commentId && this._type === 'fav') {  
196 - syncFnName = 'praiseComment';  
197 - }  
198 -  
199 - if (syncFnName) {  
200 - if (!this.auth()) {  
201 - return this.changeBtnStatus();  
202 - }  
203 -  
204 const backFn = (res) => { 196 const backFn = (res) => {
205 this.syncing = false; 197 this.syncing = false;
206 198
207 if (res.code !== 200) { 199 if (res.code !== 200) {
208 this.changeBtnStatus(); 200 this.changeBtnStatus();
209 -  
210 - if (res.code === 401) {  
211 - // TODO go_login  
212 - } else {  
213 this.$createToast && this.$createToast({ 201 this.$createToast && this.$createToast({
214 txt: res.message || '服务器开小差了', 202 txt: res.message || '服务器开小差了',
215 type: 'warn', 203 type: 'warn',
216 time: 1000 204 time: 1000
217 }).show(); 205 }).show();
218 } 206 }
219 - }  
220 }; 207 };
221 208
222 this.syncing = true; 209 this.syncing = true;
223 210
224 - this.syncService(syncFnName, { 211 + this.syncService(this.syncFnName, {
225 articleId: this.articleId, 212 articleId: this.articleId,
226 commentId: this.commentId, 213 commentId: this.commentId,
227 status: this.btnSelected 214 status: this.btnSelected
228 }).then(backFn).catch(backFn); 215 }).then(backFn).catch(backFn);
229 } 216 }
230 - }  
231 217
232 this.viewOption.emitName && this.$emit(this.viewOption.emitName, evt); 218 this.viewOption.emitName && this.$emit(this.viewOption.emitName, evt);
233 } 219 }
234 }, 220 },
235 - }; 221 +};
236 </script> 222 </script>
237 223
238 <style type="scss"> 224 <style type="scss">
@@ -10,6 +10,7 @@ import {get} from 'lodash'; @@ -10,6 +10,7 @@ import {get} from 'lodash';
10 import Lazy from 'vue-lazyload'; 10 import Lazy from 'vue-lazyload';
11 import yoho from 'common/yoho'; 11 import yoho from 'common/yoho';
12 import sdk from 'common/sdk'; 12 import sdk from 'common/sdk';
  13 +import InitClient from 'utils/init-client';
13 import 'statics/scss/common.scss'; 14 import 'statics/scss/common.scss';
14 import 'statics/scss/grass-prompt.scss'; 15 import 'statics/scss/grass-prompt.scss';
15 import 'statics/font/iconfont.css'; 16 import 'statics/font/iconfont.css';
@@ -24,6 +25,7 @@ if (window.__INITIAL_STATE__) { @@ -24,6 +25,7 @@ if (window.__INITIAL_STATE__) {
24 store.replaceState(window.__INITIAL_STATE__); 25 store.replaceState(window.__INITIAL_STATE__);
25 } 26 }
26 27
  28 +
27 window._router = get(store, 'state.yoho.context.route'); 29 window._router = get(store, 'state.yoho.context.route');
28 30
29 Vue.prop('yoho', yoho); 31 Vue.prop('yoho', yoho);
@@ -44,6 +46,8 @@ Vue.prop('api', createApi(context, store)); @@ -44,6 +46,8 @@ Vue.prop('api', createApi(context, store));
44 Vue.use(Lazy, {error: ''}); 46 Vue.use(Lazy, {error: ''});
45 47
46 48
  49 +InitClient(store);
  50 +
47 const trackPage = (path) => { 51 const trackPage = (path) => {
48 if (window._hmt) { 52 if (window._hmt) {
49 try { 53 try {
@@ -27,16 +27,6 @@ const clientTitleMixin = { @@ -27,16 +27,6 @@ const clientTitleMixin = {
27 if (title) { 27 if (title) {
28 document.title = title; 28 document.title = title;
29 } 29 }
30 - },  
31 - methods: {  
32 - auth() {  
33 - if (!this.$store.state.yoho.context.isLogin) {  
34 - this.$yoho.goLogin();  
35 - return false;  
36 - } else {  
37 - return true;  
38 - }  
39 - }  
40 } 30 }
41 }; 31 };
42 32
@@ -6,7 +6,6 @@ import storeArticle from './article'; @@ -6,7 +6,6 @@ import storeArticle from './article';
6 import storeUser from './user'; 6 import storeUser from './user';
7 import storeComment from './comment'; 7 import storeComment from './comment';
8 import storeProduct from './product'; 8 import storeProduct from './product';
9 -import plugin from './plugin';  
10 9
11 Vue.use(Vuex); 10 Vue.use(Vuex);
12 11
@@ -21,7 +20,6 @@ export function createStore(context) { @@ -21,7 +20,6 @@ export function createStore(context) {
21 product: storeProduct() 20 product: storeProduct()
22 }, 21 },
23 strict: process.env.NODE_ENV !== 'production', 22 strict: process.env.NODE_ENV !== 'production',
24 - plugins: [plugin]  
25 }); 23 });
26 24
27 const api = createApi(context, store); 25 const api = createApi(context, store);
1 -import Vue from 'vue';  
2 -  
3 -export default (store) => {  
4 - setTimeout(() => {  
5 - if (process.env.VUE_ENV !== 'server') {  
6 - window.onresize = () => {  
7 - const {clientWidth, clientHeight} = document.body;  
8 -  
9 - store.commit('SET_WINDOW_SIZE', {clientWidth, clientHeight});  
10 - };  
11 - const {clientWidth, clientHeight} = document.body;  
12 -  
13 - store.commit('SET_WINDOW_SIZE', {clientWidth, clientHeight});  
14 - let supportsPassive = false;  
15 -  
16 - try {  
17 - const opts = Object.defineProperty({}, 'passive', {  
18 - get() {  
19 - supportsPassive = true;  
20 - return true;  
21 - }  
22 - });  
23 -  
24 - window.addEventListener('test', null, opts);  
25 - } catch (e) {} //eslint-disable-line  
26 - store.commit('SET_SUPPORT_PASSIVE', {supportsPassive});  
27 -  
28 - Vue.$sdk.getUser().then(user => {  
29 - console.log(user)  
30 - })  
31 - }  
32 - }, 0); 1 +export default () => {
33 }; 2 };
@@ -33,7 +33,9 @@ export default function() { @@ -33,7 +33,9 @@ export default function() {
33 state.context.title = context.title; 33 state.context.title = context.title;
34 state.context.route = context.route; 34 state.context.route = context.route;
35 state.context.path = context.path; 35 state.context.path = context.path;
36 - state.context.isLogin = context.user.uid > 1; 36 + },
  37 + [Types.SET_LOGIN_INFO](state, {uid}) {
  38 + state.context.isLogin = uid > 1;
37 }, 39 },
38 [Types.SET_TITLE](state, {title}) { 40 [Types.SET_TITLE](state, {title}) {
39 state.context.title = title; 41 state.context.title = title;
@@ -55,8 +57,9 @@ export default function() { @@ -55,8 +57,9 @@ export default function() {
55 [Types.SET_NEED_LOGIN](state, {needLogin}) { 57 [Types.SET_NEED_LOGIN](state, {needLogin}) {
56 state.context.needLogin = needLogin; 58 state.context.needLogin = needLogin;
57 }, 59 },
58 - [Types.SET_WINDOW_SIZE](state, data) {  
59 - state.window = Object.assign(state.window, data); 60 + [Types.SET_WINDOW_SIZE](state, {clientWidth, clientHeight}) {
  61 + state.window.clientWidth = clientWidth;
  62 + state.window.clientHeight = clientHeight;
60 }, 63 },
61 [Types.SET_SUPPORT_PASSIVE](state, {supportsPassive}) { 64 [Types.SET_SUPPORT_PASSIVE](state, {supportsPassive}) {
62 state.window.supportsPassive = supportsPassive; 65 state.window.supportsPassive = supportsPassive;
@@ -3,5 +3,6 @@ export const SET_TITLE = 'SET_TITLE'; @@ -3,5 +3,6 @@ export const SET_TITLE = 'SET_TITLE';
3 export const ROUTE_CHANGE = 'ROUTE_CHANGE'; 3 export const ROUTE_CHANGE = 'ROUTE_CHANGE';
4 export const REPORT_YAS = 'REPORT_YAS'; 4 export const REPORT_YAS = 'REPORT_YAS';
5 export const SET_NEED_LOGIN = 'SET_NEED_LOGIN'; 5 export const SET_NEED_LOGIN = 'SET_NEED_LOGIN';
  6 +export const SET_LOGIN_INFO = 'SET_LOGIN_INFO';
6 export const SET_WINDOW_SIZE = 'SET_WINDOW_SIZE'; 7 export const SET_WINDOW_SIZE = 'SET_WINDOW_SIZE';
7 export const SET_SUPPORT_PASSIVE = 'SET_SUPPORT_PASSIVE'; 8 export const SET_SUPPORT_PASSIVE = 'SET_SUPPORT_PASSIVE';
  1 +import Vue from 'vue';
  2 +
  3 +export default store => {
  4 + window.onresize = () => {
  5 + const {clientWidth, clientHeight} = document.body;
  6 +
  7 + store.commit('SET_WINDOW_SIZE', {clientWidth, clientHeight});
  8 + };
  9 + const {clientWidth, clientHeight} = document.body;
  10 +
  11 + store.commit('SET_WINDOW_SIZE', {clientWidth, clientHeight});
  12 + let supportsPassive = false;
  13 +
  14 + try {
  15 + const opts = Object.defineProperty({}, 'passive', {
  16 + get() {
  17 + supportsPassive = true;
  18 + return true;
  19 + }
  20 + });
  21 +
  22 + window.addEventListener('test', null, opts);
  23 + } catch (e) {} //eslint-disable-line
  24 + store.commit('SET_SUPPORT_PASSIVE', {supportsPassive});
  25 +
  26 + Vue.$sdk.getUser().then(user => {
  27 + if (user && user.uid) {
  28 + store.commit('SET_LOGIN_INFO', user);
  29 + }
  30 + });
  31 +};