西山居工作流

公司的工作流程配置项目

发布

环境配置

  • npm i xpx -g
  • npm i nrm -g
  • nrm add xsj http://npm-registry.seasungame.com
  • nrm use xsj

脚本配置

1
2
//package.json
"publish:test": "npm run build && xpx deploy-zt@0.0.12 deploy test",

埋点

环境配置

1
npm i @xfe/st-report-sdk -s

脚本配置

入口文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
//$$tracker index.js
import {
getDiffRouteTime,
report
} from './report';

const $$tracker = {
/**
* 示例
* @param status
* @param rejectReason
*/
// clickReward1(status, rejectReason) {
// report({
// eventName: 'click_reward1',
// eventDescription: '首页领奖',
// eventDataValue: {
// status /* 是否领奖成功 (成功:success,失败:fail) */: status,
// ev_status_reason /* (领奖失败原因:积分不足) */: rejectReason,
// td_pl /* 记录距离页面加载的完成时间 */: getDiffRouteTime()
// }
// });
// },

clickIndex(userInfo) {
report({
eventName: 'click_index',
eventDescription: '开始考试',
eventDataValue: {
td_pl: getDiffRouteTime(),
passport_id: userInfo.passport,
name_id: userInfo.name
}
});
},
};

export default $$tracker;

全局方法管理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
//$$tracker report.js
import StReportSdk from '@xfe/st-report-sdk';

const params = {
projectIdentifier: 'daily' /*项目标识: 如: jx3, 必须填写!!*/ ,
eventGroup: 'daily_saohuakaoshi0505',
eventTags: [
'phhd',
'mobile'
] /* 必须填写!!专题tags,这个数组需要替换为埋点文档上的 ev_tag, 最后一个 js4_xxxx_20181204 往往是专题标识 */
};

export const stReportSdk = StReportSdk.getInstance(
params, true
// DEPLOY_ENV !==
// 'master' /* 是否开日志上报的 logger,默认是生产环境不开,平时开;想要关可以直接设为false */
);

/**
* 计算上一次路由时间,
* 对应买点中的: ev_d.td_pl(秒)
*/
export const getDiffRouteTime = StReportSdk.getDiffRouteTime;

export const report = ({
eventName /* String 事件名 一般是英文 */ ,
eventDescription /* String 事件描述 一般是中文 */ ,
eventGroup /* String 事件组,一般只有一个,例如“webstat”,若有多个,则用空格隔开,注意是字符串不是数组哦 */ ,
eventDataValue = {} /* String 事件数据*/ ,
...restProps /* 其他参数详见 sdk https://gitlab.xsjcs.cn/xfe/st-report-sdk 和 Wiki http://wiki.xsjcs.cn/pages/viewpage.action?pageId=18068827 */
}) => {
try {
stReportSdk.report({
eventName,
eventDescription,
eventDataValue,
eventGroup,
eventTags: params.eventTags,
...restProps
});
} catch (e) {
// 为了能够继续往后走, 但是能够上报
setTimeout(() => {
throw e;
});
}
};

额外文件

1
2
3
4
//$$tracker track-page-load.js
import { stReportSdk } from './report';

stReportSdk.trackPageLoad();

事件绑定

1
2
3
4
begin () {
//tracker
$$tracker.clickIndex(store.state.userInfo)
},

登陆授权

环境配置

1
npm i @xfe/universal-auth -s

脚本配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
<!-- public/index.html -->
<script>
/**
* 执行后返回:
*
* 通用模块
* window.AUTH = {
* type: loginType, // daily, wechat, qq, weibo, h5
* status: status, // success, error, require-login, 在需要授权登录时该值为: require-login
* data: data // 授权数据
* }
*
* 业务模块
* window.BUSINESS_CONFIG = {
* type: loginType, // daily, wechat, qq, weibo, h5
* status: 'success', // 目前只会 "success", 异常时直接上报, 并 alert
* data: response.data // 目前只会 "success", 业务数据
* };
*/
(function () {
/**
* 是否是正式环境
*/
var isMaster = document.documentElement.dataset.env === 'true';
/**
* 全局配置
*/
window.GLOBAL_CONFIG = {
/**
* 是否是正式环境
*/
isMaster: isMaster,
/**
* 根据环境获取 xoyo 地址
*/
getXoyoUrl: function () {
return isMaster ? 'ws.xoyo.com' : 'test-ws.xoyo.com';
},
/**
* 是否仅仅只限制 daily 登录
*/
isDailyOnly: false,
/**
* 登录类型
*/
loginType: [
isDailyApp() && 'daily',
isWeiXin() && 'wechat',
isMQQ() && 'qq',
isMWeibo() && 'weibo',
'h5'
].filter(Boolean)[0],
/**
* 当前是否是 daily app
*/
isDailyApp: isDailyApp()
};

/**
* xoyo 地址, 如: 'ws.xoyo.com' : 'test-ws.xoyo.com'
*/
var xoyoUrl = window.GLOBAL_CONFIG.getXoyoUrl();
/**
* 是否仅限 daily
*/
var isDailyOnly = window.GLOBAL_CONFIG.isDailyOnly;
/**
* 登录类型, 如: daily, wechat, qq, weibo, h5
*/
var loginType = window.GLOBAL_CONFIG.loginType;

/**
* 当仅在 daily app 场景时, 同时在非 daily app 打开当前应用时
*/
if (isDailyOnly && !isDailyApp()) {
location.href = 'https://daily.xoyo.com/mobile.html';
}

/**
* 是否是 daily app
* @return {boolean}
*/
function isDailyApp() {
return /jianghudaily/i.test(getUserAgent());
}

/**
* 获取 UA
* @return {string}
*/
function getUserAgent() {
var userAgent = navigator.userAgent || navigator.vendor || window.opera;
return userAgent.toLowerCase();
}

/**
* 判断是否 ios 设备
* @return {boolean}
*/
function isIOS() {
return (/iPad|iPhone|iPod/i.test(getUserAgent()) && !window.MSStream);
}

/**
* 判断是否是 android 设备
* @return {boolean}
*/
function isAndroid() {
return /android/i.test(getUserAgent());
}

/**
* 判断是否是手机
* @return {boolean}
*/
function isMobile() {
var userAgent = getUserAgent();
return (
/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series([46])0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i
.test(userAgent) ||
// eslint-disable-next-line
/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br([ev])w|bumb|bw-([nu])|c55\/|capi|ccwa|cdm-|cell|chtm|cldc|cmd-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc-s|devi|dica|dmob|do([cp])o|ds(12|-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly([-_])|g1 u|g560|gene|gf-5|g-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd-([mpt])|hei-|hi(pt|ta)|hp( i|ip)|hs-c|ht(c([- _agpst])|tp)|hu(aw|tc)|i-(20|go|ma)|i230|iac([ -\/])|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja([tv])a|jbro|jemu|jigs|kddi|keji|kgt([ \/])|klon|kpt |kwc-|kyo([ck])|le(no|xi)|lg( g|\/([klu])|50|54|-[a-w])|libw|lynx|m1-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t([- ov])|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30([02])|n50([025])|n7(0([01])|10)|ne(([cm])-|on|tf|wf|wg|wt)|nok([6i])|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan([adt])|pdxg|pg(13|-([1-8]|c))|phil|pire|pl(ay|uc)|pn-2|po(ck|rt|se)|prox|psio|pt-g|qa-a|qc(07|12|21|32|60|-[2-7]|i-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h-|oo|p-)|sdk\/|se(c([-01])|47|mc|nd|ri)|sgh-|shar|sie([-m])|sk-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h-|v-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl-|tdg-|tel([im])|tim-|t-mo|to(pl|sh)|ts(70|m-|m3|m5)|tx-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c([- ])|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas-|your|zeto|zte-/i
.test(userAgent.substr(0, 4)));
}

/**
* 是否是 微信 设备
* @return {boolean}
*/
function isWeiXin() {
var userAgent = getUserAgent();
return String(userAgent.match(/MicroMessenger/i)) === 'micromessenger';
}

/**
* 判断是否是手机qq
* @return {boolean}
*/
function isMQQ() {
var userAgent = getUserAgent();
var isIOSQQ = isIOS() && / QQ/i.test(userAgent);
var isAndroidQQ = isAndroid() &&
/MQQBrowser/i.test(navigator.userAgent) &&
/QQ/i.test(userAgent.split('mqqbrowser'));
return isMobile() && (isIOSQQ || isAndroidQQ);
}

/**
* 判断是否是手机微博 UA
* @return {boolean}
*/
function isMWeibo() {
var userAgent = getUserAgent();
return isMobile() && /(weibo)/.test(userAgent);
}

/**
* 创建授权对象
* {success|error} status - 授权状态, 成功或失败, success | error
* {object} data - 数据
*/
function createAuth(status, data) {
window.AUTH = {
type: loginType,
status: status,
data: data
};
return window.AUTH;
}

/**
* 创建授权成功
* @param {string} data - 授权数据
*/
function createAuthSuccess(data) {
return createAuth('success', data);
}

/**
* 创建授权错误
* @param {object} data - 授权数据
*/
function createAuthError(data) {
return createAuth('error', data);
}

/**
* 通用模块
*/
(function () {
/**
* 第三方授权登录, 微信, qq, 微博
*/
if (isWeiXin() || isMQQ() || isMWeibo()) {
/**
* 获取授权地址
* @param {object} response
* @private
*/
window.__GET_AUTH_URL__ = function (response) {
window.__GET_AUTH_URL__ = undefined;
if (response.status === 1 /* 成功 */ ) {
window.location.href = response.data.auth_url;
} else {
throw new Error('第三方获取授权地址异常: ' + JSON.stringify(response));
}
};
/**
* 获取当前用户信息
* @param response
* @private
*/
window.__GET_CURRENT_USER_INFO__ = function (response) {
window.__GET_CURRENT_USER_INFO__ = undefined;
if (response.status === 1 /* 成功 */ ) {
window.__GET_AUTH_URL__ = undefined;
/**
* 创建授权成功
*/
createAuthSuccess(response.data);
} else {
if (response.code === -14601 /*需要授权*/ ) {
document.writeln('<script src="//' + xoyoUrl + '/core/thirdlogin/get_auth_url?ts=' + new Date()
.getTime() + '&callback=__GET_AUTH_URL__&login_type=' + loginType + '&font_callback=' +
encodeURIComponent(location.href) + '">' + '<' + '/' + 'script>');
return;
}
/**
* 授权授权失败对象
*/
var errorObject = createAuthError(response);
/**
* 在异步栈抛异常, 防止主线程崩溃
*/
setTimeout(function () {
throw new Error('第三方授权异常: ' + JSON.stringify(errorObject));
});
}
};
document.writeln('<script src="//' + xoyoUrl + '/core/thirdlogin/get_current_user_info?ts=' + new Date()
.getTime() + '&callback=__GET_CURRENT_USER_INFO__">' + '<' + '/' + 'script>');
}
/**
* 判断是否是 daily app
*/
else if (isDailyApp()) {
/**
* 是否仅仅只是 daily 端
* @type {boolean}
*/
window.__DAILY_APP_AUTH__ = function (response) {
window.__DAILY_APP_AUTH__ = undefined;
if (response.status === 1 /* 成功 */ ) {
createAuthSuccess(response.data);
} else {
if (response.code === -14702 /*登录态失效,请重新登陆*/ ) {
window.location.href = 'https://jx3.seasungame.com/error-pages/index.html?login-expired';
throw new Error('DAILY_APP_AUTH 登录态失效,请重新登陆: ' + JSON.stringify(response));
}
var errorObject = createAuthError(response);
setTimeout(function () {
throw new Error('DAILY_APP_AUTH 授权异常: ' + JSON.stringify(errorObject));
});
}
};
document.writeln('<script src="//' + xoyoUrl + '/core/jhdaily/get_current_account?ts=' + new Date()
.getTime() + '&callback=__DAILY_APP_AUTH__">' + '<' + '/' + 'script>');
}
/**
* H5 判断场景
*/
else {
createAuth();
}
}());
}());
</script>
<script>
(function () {
if (window.AUTH.type === 'h5') {
var isMaster = window.GLOBAL_CONFIG.isMaster;
var getXoyoInfoUrl = isMaster ? 'pf-api.xoyo.com' : 'my-api-dev.xoyo.com';
window.__GET_XOYO_INFO__ = function (response) {
window.__GET_XOYO_INFO__ = undefined;
if (response.status === 1) {
window.AUTH.status = 'success';
window.AUTH.data = response.data;
} else if (response.code === -10402 /* 测试或正式环境未登录 */ || response.code === -20101 /* 测试或正式环境未登录 */ ) {
window.AUTH.status = 'require-login';
window.AUTH.data = response;
} else {
alert('网络异常, 请稍后重试');
throw new Error('passport/common_api/get_info 授权异常: ' + JSON.stringify(response));
}
};
document.writeln('<script src="//' + getXoyoInfoUrl + '/passport/common_api/get_info?ts=' + new Date()
.getTime() + '&callback=__GET_XOYO_INFO__">' + '<' + '/' + 'script>');
}
}());
</script>

获取数据

1
console.log(window.AUTH)

定义分享链接

环境配置

1
npm i @xfe/common-share -s

脚本配置

1
2
3
4
5
6
7
8
9
10
const commonShare = new CommonShare();
commonShare.run({
title: "剑网3骚话学院",
link: window.location.href,
imgUrl:
"https://test-zt.xoyo.com/jx3.xoyo.com/m/2019/05/15/exam/static/share_icon2.jpg",
desc: "说最骚的话,看最有趣的剑网3手中世界频道!",
// callback: () => alert('分享成功'),
swapTitleInWX: true
});