actionTemplete.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529
  1. const actionsdk = require('../action_sdk/actionsdk-1.0.0.js');
  2. const REQ_BASE = require('../action_sdk/ReqBase.js');
  3. import PAGES_JSON from "@/pages.json"
  4. export default {
  5. data() {
  6. return {
  7. ACTION_SDK:{},
  8. ACTION_ENTER_TIME : '',//页面进入时间
  9. ACTION_OUT_TIME : '',//页面离开时间
  10. ACTION_STAY_TIME : '',//页面停留时间
  11. BIND_ID:'',//行为对象id
  12. BIND_TYPE:'',//行为对象类型
  13. USER_ID:'',//当前用户id
  14. TYPE_NAME:'',//自定义类型名称
  15. SHARE_USER_ID : '',//分享用户userId
  16. CURRENT_CODE:'',//当前素材的行为code(作为分享出去的PARENT_CODE使用)
  17. PARENT_CODE : '',//当前素材的上级行为code(二次分享可用,保证行为轨迹链条完整)
  18. CURRENT_ROUTE:{},//当前页面实例
  19. USER_TIMER:null,
  20. USER_TIMER_NUM:0,
  21. OPTIONS:{},//页面入参
  22. PAGE_NAME:'',//页面名称
  23. };
  24. },
  25. async onLoad(options) {
  26. this.ACTION_SDK = actionsdk.initAction();
  27. // #ifdef H5
  28. // h5分享跳转启动页加载配置
  29. if(options.isShare){
  30. let url = window.location.href.split('?')[0]
  31. let params = this.getQueryParams()
  32. delete params.isShare
  33. let paramsStr = []
  34. for(let key in params){
  35. paramsStr.push(key + '='+params[key])
  36. }
  37. let url_copy = url
  38. if(paramsStr.length>0){
  39. url_copy = url_copy + '?' + paramsStr.join('&')
  40. }
  41. uni.setStorageSync('window_location', url_copy);
  42. uni.redirectTo({
  43. url:'/pages/launch/launch'
  44. })
  45. return false
  46. }
  47. // #endif
  48. this.OPTIONS = options
  49. if(options.scene){
  50. await this.LOAD_CODE_PARAMS(options.scene)
  51. }else if(options.x_code_id){
  52. await this.LOAD_CODE_PARAMS(options.x_code_id)
  53. }else{
  54. this.BIND_ID = options.id
  55. this.SHARE_USER_ID = options.userId
  56. this.PARENT_CODE = options.parentCode
  57. }
  58. this.CURRENT_CODE = actionsdk.creatBehaviorCode()
  59. let pageList = getCurrentPages()
  60. this.CURRENT_ROUTE = pageList[pageList.length - 1]; //页面实例
  61. this.PAGE_NAME = this.GET_PAGE_NAME()
  62. console.log('this.CURRENT_ROUTE',this.CURRENT_ROUTE)
  63. this.PAGE_BROWSE_FN()
  64. this.USER_ID = this.ACTION_SDK.getStorage('userInfo')?this.ACTION_SDK.getStorage('userInfo').id:''
  65. // 等待用户登陆成功后开始处理
  66. if(!this.USER_ID){
  67. this.USER_TIMER = setInterval(()=>{
  68. console.log('USER_TIMER')
  69. //最多10s,10s内无法获取到userId则清除定时器防止卡死
  70. this.USER_TIMER_NUM = this.USER_TIMER_NUM + 1
  71. if(this.USER_TIMER_NUM>20){
  72. clearInterval(this.USER_TIMER)
  73. this.USER_TIMER = null
  74. }
  75. if(!this.USER_ID){
  76. this.USER_ID = this.ACTION_SDK.getStorage('userInfo')?this.ACTION_SDK.getStorage('userInfo').id:''
  77. }else{
  78. clearInterval(this.USER_TIMER)
  79. this.USER_TIMER = null
  80. }
  81. },500)
  82. }else{
  83. }
  84. },
  85. onShow() {
  86. this.USER_ID = this.ACTION_SDK.getStorage('userInfo')?this.ACTION_SDK.getStorage('userInfo').id:''
  87. // 用户进入时间
  88. this.ACTION_ENTER_TIME = new Date();
  89. console.log('页面展示',this.ACTION_ENTER_TIME);
  90. switch (this.channel){
  91. case 'home':{
  92. this.PAGE_NAME = '首页' //产品
  93. } break;
  94. case 'service':{
  95. this.PAGE_NAME = '服务项目' //活动
  96. } break;
  97. case 'user':{
  98. this.PAGE_NAME = '我的' //文章
  99. } break;
  100. case 'cart':{
  101. this.PAGE_NAME = '购物车' //文章
  102. } break;
  103. default:{
  104. } break;
  105. }
  106. },
  107. onHide() {
  108. // 解决onHide重复调用问题
  109. if(!this.CURRENT_ROUTE.route) return false
  110. // 用户退出时间
  111. this.ACTION_OUT_TIME = new Date();
  112. //停留时间(毫秒)
  113. this.ACTION_STAY_TIME = this.ACTION_OUT_TIME.getTime() - this.ACTION_ENTER_TIME.getTime();
  114. console.log('页面隐藏' + this.CURRENT_ROUTE.route + ':' + this.ACTION_STAY_TIME);
  115. console.log('---用户浏览---',Math.ceil(this.ACTION_STAY_TIME/1000))
  116. this.SEND_BROWSE_FN()
  117. },
  118. onUnload() {
  119. // 解决onHide重复调用问题
  120. if(!this.CURRENT_ROUTE.route) return false
  121. // 用户退出时间
  122. this.ACTION_OUT_TIME = new Date();
  123. //停留时间(毫秒)
  124. this.ACTION_STAY_TIME = this.ACTION_OUT_TIME.getTime() - this.ACTION_ENTER_TIME.getTime();
  125. console.log('页面卸载' + this.CURRENT_ROUTE.route + ':' + this.ACTION_STAY_TIME);
  126. console.log('---用户浏览总时长---',Math.ceil(this.ACTION_STAY_TIME/1000))
  127. this.SEND_BROWSE_FN()
  128. },
  129. methods: {
  130. // 获取参数
  131. getQueryParams() {
  132. const url = window.location.search;
  133. const params = url
  134. .substring(1)
  135. .split('&')
  136. .reduce((result, param) => {
  137. const [key, value] = param.split('=');
  138. result[decodeURIComponent(key)] = decodeURIComponent(value);
  139. return result;
  140. }, {});
  141. return params;
  142. },
  143. // 页面浏览行为个性化页面处理
  144. PAGE_BROWSE_FN(){
  145. switch (this.CURRENT_ROUTE.route){
  146. case 'product/detail/detail':{
  147. this.BIND_TYPE = 1 //产品
  148. } break;
  149. case 'match/activityDetail/activityDetail':{
  150. this.BIND_TYPE = 2 //活动
  151. } break;
  152. case 'topic/content/content':{
  153. this.BIND_TYPE = 3 //文章
  154. } break;
  155. case 'topic/case/case':{
  156. this.BIND_TYPE = 3 //文章
  157. this.TYPE_NAME = '案例'
  158. } break;
  159. case 'card/index/index':{
  160. this.BIND_TYPE = 7 //名片
  161. this.BIND_ID = this.OPTIONS.cardId
  162. } break;
  163. case 'leaflet/detail/index':{
  164. this.BIND_TYPE = 8 //素材
  165. } break;
  166. case 'topic/solDet/solDet':{
  167. this.BIND_TYPE = 9 //专题
  168. } break;
  169. case 'promote/info/info':{
  170. this.BIND_TYPE = 12 //合伙人招募页面
  171. this.BIND_ID = 0 //
  172. } break;
  173. case 'martial/content/index':{
  174. this.BIND_TYPE = 8 //文章
  175. this.TYPE_NAME = '软文'
  176. } break;
  177. case 'martial/leaflet/index':{
  178. this.BIND_TYPE = 8 //宣传彩页
  179. this.TYPE_NAME = '宣传彩页'
  180. } break;
  181. case 'martial/file/index':{
  182. this.BIND_TYPE = 8 //宣传彩页
  183. this.TYPE_NAME = '文件'
  184. } break;
  185. case 'martial/video/index':{
  186. this.BIND_TYPE = 8 //宣传彩页
  187. this.TYPE_NAME = '文件'
  188. } break;
  189. default:{
  190. this.BIND_TYPE = 14
  191. this.BIND_ID = ''
  192. } break;
  193. }
  194. },
  195. /**
  196. * 修改参数(需要修改参数时传入对应需要修改的参数即可)
  197. * @param BIND_TYPE 行为对象类型
  198. * @param BIND_ID 行为对象id
  199. * @param USER_ID 当前用户id
  200. * @param SHARE_USER_ID 分享用户id
  201. * @param PARENT_CODE 上级行为code(用与二次转发)
  202. * @param TYPE_NAME 自定义类型名称
  203. * @param PAGE_NAME 自定义页面标题
  204. */
  205. PAGE_DATA_INIT_FN({
  206. BIND_TYPE = '',
  207. BIND_ID = '',
  208. USER_ID = '',
  209. SHARE_USER_ID = '',
  210. PARENT_CODE = '',
  211. TYPE_NAME = '',
  212. PAGE_NAME = ''
  213. }={}){
  214. if(BIND_TYPE) this.BIND_TYPE = BIND_TYPE
  215. if(BIND_ID) this.BIND_ID = BIND_ID
  216. if(USER_ID) this.USER_ID = USER_ID
  217. if(SHARE_USER_ID) this.SHARE_USER_ID = SHARE_USER_ID
  218. if(PARENT_CODE) this.PARENT_CODE = PARENT_CODE
  219. if(TYPE_NAME) this.TYPE_NAME = TYPE_NAME
  220. if(PAGE_NAME) this.PAGE_NAME = PAGE_NAME
  221. },
  222. /**
  223. * 记录用户浏览行为,浏览行为上报(参数非必传,只有需要修改参数时传入对应需要修改的参数即可)
  224. * @param BIND_TYPE 行为对象类型
  225. * @param BIND_ID 行为对象id
  226. * @param USER_ID 当前用户id
  227. * @param SHARE_USER_ID 分享用户id
  228. * @param PARENT_CODE 上级行为code(用与二次转发)
  229. */
  230. SEND_BROWSE_FN ({
  231. BIND_TYPE = this.BIND_TYPE,
  232. BIND_ID = this.BIND_ID,
  233. USER_ID = this.USER_ID,
  234. SHARE_USER_ID = this.SHARE_USER_ID,
  235. PARENT_CODE = this.PARENT_CODE
  236. }={}){
  237. // console.log(BIND_TYPE,BIND_ID,USER_ID,SHARE_USER_ID,PARENT_CODE)
  238. let postObj = {
  239. type:BIND_TYPE,
  240. bindId:BIND_ID,
  241. uid:USER_ID,
  242. shareUid:SHARE_USER_ID,
  243. parentCode:PARENT_CODE,
  244. code:this.CURRENT_CODE,
  245. pageUri:this.CURRENT_ROUTE.route,
  246. readTime:this.ACTION_STAY_TIME?Math.ceil(this.ACTION_STAY_TIME/1000):null
  247. }
  248. // 自定义类型名称
  249. if(this.TYPE_NAME) postObj.typeName = this.TYPE_NAME
  250. // 如果是页面浏览
  251. if(postObj.type==14){
  252. postObj.content = `浏览了${this.PAGE_NAME}页面`;
  253. postObj.typeName = this.PAGE_NAME
  254. }
  255. actionsdk.saveBrowse(postObj);
  256. },
  257. /**
  258. * 记录用户分享行为,分享行为上报
  259. * @param BIND_TYPE 行为对象类型
  260. * @param BIND_ID 行为对象id
  261. * @param USER_ID 当前用户id
  262. * @param SHARE_USER_ID 分享用户id
  263. * @param PARENT_CODE 上级行为code(用与二次转发)
  264. */
  265. SEND_SHARE_FN ({
  266. BIND_TYPE = this.BIND_TYPE,
  267. BIND_ID = this.BIND_ID,
  268. USER_ID = this.USER_ID,
  269. SHARE_USER_ID = this.SHARE_USER_ID,
  270. PARENT_CODE = this.PARENT_CODE
  271. }={}){
  272. let postObj = {
  273. behaviorType:5,
  274. type:BIND_TYPE,
  275. bindId:BIND_ID,
  276. uid:USER_ID,
  277. shareUid:SHARE_USER_ID,
  278. parentCode:PARENT_CODE,
  279. code:this.CURRENT_CODE
  280. }
  281. // 自定义类型名称
  282. if(this.TYPE_NAME) postObj.typeName = this.TYPE_NAME
  283. // 分享行为固定behaviorType 5
  284. // 延后分享是因为分享不是在成功回调调用的,导致浏览上报事件在分享上报事件前执行了,延后1s可保证时序性
  285. setTimeout(()=>{
  286. actionsdk.saveBehavior(postObj);
  287. },1000)
  288. },
  289. /**
  290. * 分享行为预处理(处理分享出去的PARENT_CODE,参数按分享参数传入,分享时取该方法返回的参数)
  291. * @param path 分享路径
  292. * @param sendShare 是否立即触发分享行为上报,默认不开启
  293. * @param codeScene 生成小程序码时的自定义参数,object
  294. */
  295. SHARE_BEHAVIOR_FN({
  296. path = '',
  297. sendShare = false,
  298. codeScene = {}
  299. }={}){
  300. if(!this.CURRENT_CODE){
  301. this.CURRENT_CODE = actionsdk.creatBehaviorCode()
  302. }
  303. if(sendShare){
  304. this.SEND_SHARE_FN()
  305. }
  306. // 小程序码参数拼接parentCode
  307. codeScene.parentCode = this.CURRENT_CODE
  308. // 分享路径拼接parentCode
  309. if(path.indexOf('?')>-1){
  310. path = path + '&parentCode='+this.CURRENT_CODE
  311. }else{
  312. path = path + '?parentCode='+this.CURRENT_CODE
  313. }
  314. return {
  315. path:path,
  316. codeScene:codeScene
  317. }
  318. },
  319. /**
  320. * 记录用户收藏行为,收藏行为上报
  321. * @param BIND_TYPE 行为对象类型
  322. * @param BIND_ID 行为对象id
  323. * @param USER_ID 当前用户id
  324. * @param SHARE_USER_ID 分享用户id
  325. * @param PARENT_CODE 上级行为code(用与二次转发)
  326. */
  327. SEND_COLLECT_FN ({
  328. BIND_TYPE = this.BIND_TYPE,
  329. BIND_ID = this.BIND_ID,
  330. USER_ID = this.USER_ID,
  331. SHARE_USER_ID = this.SHARE_USER_ID,
  332. PARENT_CODE = this.PARENT_CODE,
  333. }={}){
  334. let postObj = {
  335. behaviorType:2,
  336. type:BIND_TYPE,
  337. bindId:BIND_ID,
  338. uid:USER_ID,
  339. shareUid:SHARE_USER_ID,
  340. parentCode:PARENT_CODE,
  341. code:this.CURRENT_CODE
  342. }
  343. // 收藏行为固定behaviorType 2
  344. actionsdk.saveBehavior(postObj);
  345. },
  346. /**
  347. * 其他行为上报
  348. * @param BEHAVIOR_TYPE 行为类型
  349. * @param BIND_TYPE 行为对象类型
  350. * @param BIND_ID 行为对象id
  351. * @param USER_ID 当前用户id
  352. * @param CONTENT 日志文案(如:'浏览了xxx文章')
  353. * @param READ_TIME 行为时长(如:'浏览时长',单位s)
  354. * @param TYPE_NAME 自定义类型名称
  355. * @param SHARE_USER_ID 分享用户id
  356. * @param PARENT_CODE 上级行为code(用与二次转发)
  357. */
  358. SEND_SELF_FN ({
  359. BEHAVIOR_TYPE = '',
  360. BIND_TYPE = this.BIND_TYPE,
  361. BIND_ID = this.BIND_ID,
  362. USER_ID = this.USER_ID,
  363. CONTENT = '',
  364. READ_TIME = '',
  365. TYPE_NAME = '',
  366. SHARE_USER_ID = this.SHARE_USER_ID,
  367. PARENT_CODE = this.PARENT_CODE,
  368. }={}){
  369. if(!BEHAVIOR_TYPE) {
  370. throw new Error("未传入行为类型")
  371. return false
  372. }
  373. let postObj = {
  374. behaviorType:BEHAVIOR_TYPE,
  375. type:BIND_TYPE,
  376. bindId:BIND_ID,
  377. uid:USER_ID,
  378. shareUid:SHARE_USER_ID,
  379. parentCode:PARENT_CODE,
  380. code:this.CURRENT_CODE,
  381. content:CONTENT,
  382. pageUri:this.CURRENT_ROUTE.route,
  383. readTime:READ_TIME,
  384. TYPE_NAME:TYPE_NAME
  385. }
  386. actionsdk.saveBehavior(postObj);
  387. },
  388. /**
  389. * 记录用户点赞行为,点赞行为上报
  390. * @param BIND_TYPE 行为对象类型
  391. * @param BIND_ID 行为对象id
  392. * @param USER_ID 当前用户id
  393. * @param SHARE_USER_ID 分享用户id
  394. * @param PARENT_CODE 上级行为code(用与二次转发)
  395. * @param IS_THUMBS 是否是点赞,false为取消点赞
  396. */
  397. SEND_COLLECT_FN ({
  398. BIND_TYPE = this.BIND_TYPE,
  399. BIND_ID = this.BIND_ID,
  400. USER_ID = this.USER_ID,
  401. SHARE_USER_ID = this.SHARE_USER_ID,
  402. PARENT_CODE = this.PARENT_CODE,
  403. IS_THUMBS = true
  404. }={}){
  405. let postObj = {
  406. behaviorType:3,
  407. type:BIND_TYPE,
  408. bindId:BIND_ID,
  409. uid:USER_ID,
  410. shareUid:SHARE_USER_ID,
  411. parentCode:PARENT_CODE,
  412. code:this.CURRENT_CODE,
  413. IS_THUMBS:IS_THUMBS
  414. }
  415. // 点赞行为固定behaviorType 3
  416. if(IS_THUMBS){
  417. actionsdk.saveBehavior(postObj);
  418. }else{
  419. actionsdk.removeBehavior(postObj);
  420. }
  421. },
  422. // 获取行为接口请求参数(为实现部分项目未埋点时可通过后台接口埋点的冗余方案,纯后台埋点无行为完整链条,只有传入前端参数才能保证行为链条完整)
  423. GET_API_DATA(){
  424. let data = {
  425. shareUid: this.SHARE_USER_ID,
  426. code:this.CURRENT_CODE,
  427. shareCode: this.PARENT_CODE,
  428. };
  429. var deviceInfo = this.ACTION_SDK.getStorage('deviceInfo');
  430. // #ifdef APP-PLUS
  431. var sysMac = this.ACTION_SDK.getStorage('sysMac');
  432. // #endif
  433. var device_info = {};
  434. if (deviceInfo) {
  435. data.model = deviceInfo.deviceModel;
  436. data.manufacturer = deviceInfo.deviceBrand;
  437. data.os = deviceInfo.osName;
  438. data.osVersion = deviceInfo.osVersion;
  439. data.browser = deviceInfo.browserName;
  440. data.browserVersion = deviceInfo.browserVersion;
  441. data.deviceId = deviceInfo.deviceId;
  442. // #ifdef APP-PLUS
  443. if (sysMac) {
  444. data.sysMac = sysMac;
  445. }
  446. // #endif
  447. }
  448. return data
  449. },
  450. // 扫码进入时解码方法
  451. LOAD_CODE_PARAMS(scene) {
  452. return new Promise((resolve, reject) => {
  453. let form = {
  454. scene: scene
  455. };
  456. if (!scene) {
  457. resolve();
  458. return false;
  459. }
  460. this.ACTION_SDK.getRequestAPI('/api/code/params', form, data => {
  461. let res = JSON.parse(data.scene);
  462. if(data.userId){
  463. this.SHARE_USER_ID = data.userId
  464. }
  465. if(res.id){
  466. this.BIND_ID = res.id
  467. }
  468. if(res.userId){
  469. this.SHARE_USER_ID = res.userId
  470. }
  471. if(res.parentCode){
  472. this.PARENT_CODE = res.parentCode
  473. }
  474. resolve();
  475. });
  476. });
  477. },
  478. // 获取页面标题
  479. GET_PAGE_NAME(){
  480. let name = this.CURRENT_ROUTE.route
  481. console.log('GET_PAGE_NAME',PAGES_JSON)
  482. for(let key in PAGES_JSON){
  483. let getCurrentStyle = PAGES_JSON.pages.find((item) => item.path == this.CURRENT_ROUTE.route);
  484. if(getCurrentStyle){
  485. return getCurrentStyle.style&&getCurrentStyle.style.navigationBarTitleText?getCurrentStyle.style.navigationBarTitleText:getCurrentStyle.path
  486. }else{
  487. for(let i=0;i<PAGES_JSON.subPackages.length;i++){
  488. let subPackages = PAGES_JSON.subPackages[i]
  489. let getCurrentStyle = subPackages.pages.find((item) => subPackages.root+'/'+item.path == this.CURRENT_ROUTE.route);
  490. if(getCurrentStyle){
  491. return getCurrentStyle.style&&getCurrentStyle.style.navigationBarTitleText?getCurrentStyle.style.navigationBarTitleText:getCurrentStyle.path
  492. }
  493. }
  494. }
  495. }
  496. return name
  497. }
  498. }
  499. };