@qywh/package 0.0.3-beta01 → 0.0.3-beta05

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/common/actions/index.ts +2 -5
  2. package/common/actions/jumpXcxToQuestion.ts +57 -0
  3. package/common/actions/link.ts +0 -310
  4. package/common/compnents/dialog/index.vue +1 -1
  5. package/common/index.ts +1 -5
  6. package/lib/cdnUrl.ts +1 -8
  7. package/lib/httpdns-request.ts +3 -62
  8. package/lib/methods/actions-fn.ts +69 -519
  9. package/lib/methods/jump.ts +3 -21
  10. package/lib/request.ts +1 -6
  11. package/lib/utils/domain-config.ts +2 -132
  12. package/lib/utils/format-img.ts +3 -17
  13. package/lib/utils/index.ts +1 -4
  14. package/lib/utils/logParamHandle.ts +138 -0
  15. package/package.json +1 -1
  16. package/packages/qy-anchor/components/index.vue +4 -4
  17. package/packages/qy-atmosphere-countdown/settings/index.ts +2 -3
  18. package/packages/qy-atmosphere-countdownv2/settings/index.ts +2 -2
  19. package/packages/qy-button/components/index.vue +2 -2
  20. package/packages/qy-button/components/static/default-btn.png +0 -0
  21. package/packages/qy-button/settings/applet/v1.ts +2 -3
  22. package/packages/qy-button/settings/applet/v2.ts +2 -3
  23. package/packages/qy-container/components/index.vue +4 -4
  24. package/packages/qy-countdown/settings/index.ts +2 -3
  25. package/packages/qy-dialog/components/index.vue +30 -30
  26. package/packages/qy-hotarea/components/index.vue +2 -2
  27. package/packages/qy-limit-countdown/components/index.vue +1 -1
  28. package/packages/qy-limit-countdown/settings/index.ts +2 -3
  29. package/packages/qy-out-form-input/components/index.vue +1 -1
  30. package/packages/qy-out-form-select/components/index.vue +1 -1
  31. package/packages/qy-out-form-submit-button/components/index.vue +18 -18
  32. package/packages/qy-out-form-submit-button/components/static/default-btn.png +0 -0
  33. package/packages/qy-out-success-wechat-diversion/components/index.vue +120 -745
  34. package/packages/qy-out-success-wechat-diversion/menu.ts +1 -1
  35. package/packages/qy-out-success-wechat-diversion/settings/index.ts +5 -424
  36. package/packages/qy-out-wx-auth-button/components/index.vue +4 -4
  37. package/packages/qy-out-wx-auth-button/components/static/default-btn.png +0 -0
  38. package/packages/qy-out-wx-auth-button/settings/applet/v1.ts +2 -2
  39. package/packages/qy-out-wx-auth-button/settings/index.ts +2 -2
  40. package/packages/qy-page/components/index.vue +1 -1
  41. package/packages/qy-page/components/out-weixin-share.ts +49 -81
  42. package/packages/qy-picture/components/index.vue +1 -1
  43. package/packages/qy-picture/components/static/single_pic-2.png +0 -0
  44. package/packages/qy-picture/settings/applet/v1.ts +2 -2
  45. package/packages/qy-picture/settings/index.ts +2 -2
  46. package/packages/qy-rect/components/index.vue +2 -2
  47. package/typings/enum/saleChannelConfig.ts +1 -1
  48. package/typings/index.d.ts +0 -1
  49. package/common/actions/jumpXcx.ts +0 -20
  50. package/common/domain.ts +0 -12
  51. package/common/service.ts +0 -65
  52. package/lib/baseUrl.ts +0 -12
  53. package/lib/checkRepeat.ts +0 -28
  54. package/lib/utils/environment.ts +0 -39
  55. package/lib/utils/order-recall.ts +0 -26
  56. package/lib/utils/weixin.ts +0 -160
  57. package/lib/utils/wxGroupManage.ts +0 -211
  58. package/lib/zyb-yike-utils/feWechatMultiterminal.ts +0 -103
  59. package/lib/zyb-yike-utils/logParamHandle.ts +0 -298
  60. package/packages/qy-seckill/actions/index.ts +0 -1
  61. package/packages/qy-seckill/components/index.vue +0 -263
  62. package/packages/qy-seckill/index.ts +0 -18
  63. package/packages/qy-seckill/menu.ts +0 -6
  64. package/packages/qy-seckill/settings/index.ts +0 -101
  65. package/packages/qy-seckill/static/clock.png +0 -0
  66. package/typings/enum/coupon.ts +0 -5
  67. /package/lib/{zyb-yike-utils → utils}/cookieExt.ts +0 -0
  68. /package/lib/{zyb-yike-utils → utils}/guid.ts +0 -0
  69. /package/lib/{zyb-yike-utils → utils}/sparkMD5.js +0 -0
  70. /package/lib/{zyb-yike-utils → utils}/urlExt.ts +0 -0
  71. /package/lib/{zyb-yike-utils → utils}/utils.ts +0 -0
@@ -1,103 +0,0 @@
1
- // @ts-nocheck
2
- import logParamHandle from './logParamHandle'
3
- import { environment } from '../utils'
4
- import { cubeExtendDomain } from '../../common/service'
5
- import { ENV_KEYWORDS, DOCKER_TEMPLATES } from '../utils/domain-config'
6
-
7
- let url = location.href
8
- // 拼接参数方法
9
- const paramHandle = {
10
- // 参数全部拼接;
11
- getSpliceStr (paramsObj) {
12
- let str = ''
13
- const params = []
14
- if (Object.keys(paramsObj).length !== 0) {
15
- Object.keys(paramsObj).forEach((key) => {
16
- params.push([key, paramsObj[key]].join('='))
17
- })
18
- str = params.join('&')
19
- }
20
- return str
21
- },
22
- // 重复的参数部分不拼接;
23
- getExtraSpliceStr (options, extra) {
24
- var paramString = ''
25
- var extraArr = []
26
- if (typeof extra === 'string') {
27
- extraArr.push(extra)
28
- } else {
29
- extraArr = extra
30
- }
31
- for (var p in options) {
32
- if (p !== 'from' &&
33
- extraArr.indexOf(p) === -1) {
34
- paramString = paramString + '&' + p + '=' + options[p]
35
- }
36
- }
37
- return paramString
38
- }
39
- }
40
-
41
- const Multiterminal = {
42
- // 端外事件使用方法
43
- goToOutPayment (options) {
44
- console.log('goToOutPayment事件', JSON.stringify(options))
45
- const { orderPageType, orderPage, orderPageGroupId, saleChannel, successPageId, successGroupId } = options
46
- let originName = ''
47
- let urlPath = ''
48
- const shipName = window.location.host.split('-')[1]
49
- // 兼容线上地址前置多店铺拆单,跳转cube-extend订单页
50
- if (options.addressPostposition === 0) {
51
- if (environment.isDocker()) {
52
- // ship 线下
53
- originName = `https://${DOCKER_TEMPLATES.cubeExtend.replace('{shipName}', shipName || 'lidingkang')}`
54
- }
55
- if (environment.isOnline()) {
56
- // 线上
57
- originName = cubeExtendDomain
58
- }
59
- const skuList = [{ skuId: options.courseInfoArr[0].courseId, count: 1 }]
60
- const { actInfo } = window.__PAGE_DATA__
61
- urlPath = `/static/cube-extend/orderXxlAd.html?saleType=2&actId=${actInfo.actId}&successGroupId=${successGroupId}&successPageId=${successPageId}&skuList=${JSON.stringify(skuList)}&saleChannelId=${saleChannel}&marketType=CUBE`
62
- } else {
63
- // 跳转魔方页面
64
- if (orderPage) {
65
- const { actInfo } = window.__PAGE_DATA__
66
- originName = window.location.origin
67
- if (environment.isOnline()) {
68
- urlPath = `/static/hy/cornucopia/${orderPage}.html?actId=${actInfo.actId}&groupId=${orderPageGroupId}&pageId=${orderPage}&saleChannel=${saleChannel}&skuInfo=${encodeURIComponent(options.skuInfo)}`
69
- } else if (window.location.origin.indexOf('localhost') !== -1) {
70
- urlPath = `/cube-ssr/activity/${actInfo.actId}/1?preview=1&pageId=${orderPage}&source=2&saleChannel=${saleChannel}&skuInfo=${encodeURIComponent(options.skuInfo)}`
71
- } else {
72
- urlPath = `/cube/act/display/out?actId=${actInfo.actId}&groupId=${orderPageGroupId}&pageId=${orderPage}&saleChannel=${saleChannel}&skuInfo=${encodeURIComponent(options.skuInfo)}`
73
- }
74
- }
75
- }
76
-
77
- let url = originName + urlPath
78
- // 添加flowPond
79
- let finallyPath: any = url + '&lastfrom=' + logParamHandle.getLastfrom() + '&flowPond=' + logParamHandle.getUrlFlowPond()
80
- console.log('finallyPath', finallyPath)
81
- location.href = logParamHandle.urlHandle(finallyPath, true)
82
- },
83
- goToOutCSPayment (options) {
84
- const { actInfo } = window.__PAGE_DATA__
85
- let originName = ''
86
- const { successPageId, mustAddress, successPageGroupId, saleChannel, skuInfo } = options
87
- const skuList = (JSON.parse(decodeURIComponent(decodeURIComponent(skuInfo))) || []).map(item => Object.assign({}, item, { count: 1 }))
88
- const shipName = window.location.host.split('-')[1]
89
- if (window.location.origin.indexOf(ENV_KEYWORDS.docker) !== -1) {
90
- // ship 线下
91
- originName = `https://${DOCKER_TEMPLATES.www.replace('{shipName}', shipName || 'lidingkang').replace('{suffix}', window.location.origin.includes('.com') ? '.com' : '.cc')}`
92
- } else {
93
- // 线上
94
- originName = `https://www.xingmangmeixue${window.location.origin.includes('.com') ? '.com' : '.cc'}`
95
- }
96
- let url = `${originName}/static/xmpage/xmOrder.html?actId=${actInfo.actId}&groupId=${successPageGroupId}&successPageId=${successPageId}&mustAddress=${mustAddress}&saleChannel=${saleChannel}&skuInfo=${encodeURIComponent(JSON.stringify(skuList))}`
97
- let finallyPath: any = url + '&lastfrom=' + logParamHandle.getLastfrom() + '&flowPond=' + logParamHandle.getUrlFlowPond()
98
- console.log('跳转星芒订单页---', finallyPath)
99
- location.href = logParamHandle.urlHandle(finallyPath, true)
100
- }
101
- }
102
-
103
- export default Multiterminal
@@ -1,298 +0,0 @@
1
- // @ts-nocheck
2
- /*eslint-disable*/
3
- import urlExt from './urlExt';
4
- import isPlainObject from 'lodash/isPlainObject';
5
- import isEmptyObject from 'lodash/isEmpty';
6
- import extend from 'lodash/extend';
7
- import cdnUrl from '../cdnUrl'
8
- import { ENV_KEYWORDS } from '../utils/domain-config'
9
-
10
- let currentPageURL = location.href // 用于兼容 vue # 号后边的参数getQuery无法获取的问题
11
- // path处理
12
- let urlLogPath = urlExt.getQuery('logpath', currentPageURL) || '';
13
- // lastFrom 处理
14
- let urlLastFrom = urlExt.getQuery('lastfrom', currentPageURL) || '';
15
- // 微信公众号订单授权免登录透传参数 isWxYike
16
- let urlWxYike = urlExt.getQuery('isWxYike', currentPageURL) || '';
17
- // saleChannelId参数透传
18
- let urlSaleChannelId = urlExt.getQuery('saleChannelId', currentPageURL) || '';
19
-
20
- /* fr参数:表示最初经过的渠道位
21
- fr参数要求一直透传下去,如果遇到新的fr参数,不替换。
22
- 因为端内公共参数里面已经用了fr这个key,所以打点时fr会改成orifrom作为key
23
- */
24
- let urlOriFrom = urlExt.getQuery('orifrom', currentPageURL) || urlExt.getQuery('fr', currentPageURL) || '';
25
- let urlFlowPond = urlExt.getQuery('flowPond', currentPageURL) || ''; // ab侧区分用户
26
-
27
-
28
- if (new RegExp(`^https?://(((qa)?test\\d+?)|(.+?-docker))\\.${ENV_KEYWORDS.docker}\\.com/.*?`).test(currentPageURL)) {
29
- if (/^(null|%20|%22%22|%27%27)$/.test(urlLastFrom) || !urlLastFrom) {
30
- // window.alert('lastfrom为空,请设置lastfrom')
31
- try {
32
- toastText('lastfrom为空,请设置lastfrom')
33
- } catch (e) {
34
- console.log('lastfrom为空,请设置lastfrom')
35
- }
36
- }
37
- }
38
- function toastText(text) {
39
- //toast提示
40
- let toastTimer;
41
- let yikeLogToast = document.getElementById('yike-log-toast');
42
- if (yikeLogToast) {
43
- if (toastTimer) {
44
- clearTimeout(toastTimer);
45
- }
46
- document.body.removeChild(yikeLogToast);
47
- }
48
- let toastHtml = document.createElement('div');
49
- toastHtml.id = 'yike-log-toast';
50
- toastHtml.innerHTML = `
51
- <div style="position: fixed;width:100%;left:0;top: 200px;text-align: center;">
52
- <p style="background: rgba(0,0,0,.7);color: #fff;border-radius: 100px;display: inline-block; padding: 10px 15px;font-size:14px;">${text}</p>
53
- </div>
54
- `;
55
- document.body?.appendChild(toastHtml);
56
- toastTimer = setTimeout(function() {
57
- document.body.removeChild(toastHtml);
58
- },2000);
59
- }
60
- function setLogPath(data) {
61
- if (data && isPlainObject(data) && !isEmptyObject(data)) { // 如果有data参数,且为一个纯粹的对象,且不是一个空对象
62
- var pageId = data.id || '';
63
- try {
64
- delete data.id;
65
- } catch(e) {
66
- // console.log(e);
67
- }
68
- var logPath = getPath(urlLogPath, pageId, data);
69
- urlLogPath = logPath
70
- }
71
- }
72
- function getLogPath() {
73
- return urlLogPath
74
- }
75
-
76
- function setLastfrom(lastfrom) {
77
- urlLastFrom = lastfrom
78
- }
79
- function getLastfrom() {
80
- return urlLastFrom
81
- }
82
-
83
- function getOriFrom() {
84
- return urlOriFrom;
85
- }
86
- function setOriFrom(fr) {
87
- urlOriFrom = fr
88
- }
89
- function setFlowPond(flowPond) {
90
- if (isPlainObject(flowPond) && !isEmptyObject(flowPond)) {
91
- try {
92
- let tmpFlowPond = JSON.parse(decodeURIComponent(decodeURIComponent(urlFlowPond)));
93
- urlFlowPond = encodeURIComponent(JSON.stringify(extend(tmpFlowPond, flowPond)))
94
- } catch (e) {
95
- urlFlowPond = encodeURIComponent(JSON.stringify(flowPond));
96
- }
97
- }
98
- }
99
- function mergeFlowPond(flowPond) {
100
- try {
101
- let targetFlowPond = JSON.parse(decodeURIComponent(decodeURIComponent(flowPond)));
102
- let sourceFlowPond = JSON.parse(decodeURIComponent(decodeURIComponent(urlFlowPond)));
103
- return encodeURIComponent(JSON.stringify(extend(sourceFlowPond, targetFlowPond)));
104
- } catch (e) {
105
- return flowPond;
106
- }
107
- }
108
-
109
- // 重置flowPond
110
- function resetFlowPond() {
111
- urlFlowPond = urlExt.getQuery('flowPond', currentPageURL) || ''; // ab侧区分用户
112
- }
113
-
114
- // 重置lastfrom
115
- function resetLastfrom() {
116
- urlLastFrom = urlExt.getQuery('lastfrom', currentPageURL) || '';
117
- }
118
-
119
- // 重置orifrom
120
- function resetOrifrom() {
121
- urlOriFrom = urlExt.getQuery('orifrom', currentPageURL) || urlExt.getQuery('fr', currentPageURL) || '';
122
- }
123
-
124
- function getUrlFlowPond() {
125
- return encodeURIComponent(decodeURIComponent(decodeURIComponent(urlFlowPond)));
126
- }
127
- function getFlowPond() {
128
- try {
129
- let customFlowPond = (window as any).__PAGE_DATA__.pageInfo.customFlowPond // 自定义追加flowPond
130
- let newFlowPond = JSON.parse(decodeURIComponent(urlFlowPond));
131
- let paramString = '';
132
- if (customFlowPond && typeof customFlowPond === 'object') {
133
- newFlowPond = {
134
- ...newFlowPond,
135
- ...customFlowPond
136
- }
137
- }
138
- for(let key in newFlowPond) {
139
- if (typeof newFlowPond[key] === 'number') {
140
- paramString = `${paramString}&${key}=${newFlowPond[key]}`;
141
- } else {
142
- paramString = `${paramString}&${key}=${encodeURIComponent(newFlowPond[key])}`;
143
- }
144
- }
145
- return encodeURIComponent(paramString.replace(/^&/, ''));
146
- } catch (e) {
147
- return urlFlowPond;
148
- }
149
- }
150
-
151
- function getFlowPondKey(key) {
152
- try {
153
- const urlFlowPondObj = JSON.parse(decodeURIComponent(decodeURIComponent(urlFlowPond)));
154
- return urlFlowPondObj[key] !== undefined ? urlFlowPondObj[key] : urlFlowPond;
155
- } catch (e) {
156
- return urlFlowPond;
157
- }
158
- }
159
-
160
- /**
161
- * 按照规则拼接logpath
162
- * @param prePath 原logpath
163
- * @param pageId 页面id
164
- * @param pathParams 页面参数
165
- * @returns {string} 拼好的logpath
166
- */
167
- function getPath(prePath, pageId, pathParams) {
168
- if (!pageId) { // 如果不存在pageId
169
- return '.' // 此处PM文路沟通后说返回.或者?都可以
170
- } else {
171
- var curPath = pageId;
172
- if (isPlainObject(pathParams) && !isEmptyObject(pathParams)) {
173
- for(var p in pathParams) {
174
- curPath = curPath + '(' + p + '!' + pathParams[p] + ')';
175
- }
176
- }
177
- return prePath ? (prePath + '__' + curPath) : curPath;
178
- }
179
- }
180
-
181
- function withBaseURL(jumpUrl) {
182
- const host = window.location.host
183
- if (/^(http|https):\/\/([^\/]+)/i.test(jumpUrl)) { // 有其他域名,不作处理
184
- return jumpUrl;
185
- }
186
-
187
- let baseURL = cdnUrl;
188
- return `${baseURL}${jumpUrl}`;
189
- }
190
-
191
- /**
192
- * 对传入的url进行参数处理
193
- * @param url 端内或端外的url
194
- * @returns {*}
195
- */
196
- function urlHandle(url, isMerge = false) {
197
- console.log('urlHandle===========:', url)
198
- url = url? withBaseURL(url) : currentPageURL
199
- var urlParts = url ? url.split('?') : []
200
- var normalUrl = url ? url.split('?')[0] : ''
201
- var paramsUrl = url ? url.split('?')[1] : ''
202
- if (urlParts.length > 2) {
203
- // 说明链接参数中有多余的? 将后半部分组装回去
204
- var realParamsUrl = ''
205
- urlParts.forEach((item, index) => {
206
- if (index !== 0 && index !== (urlParts.length - 1)) {
207
- realParamsUrl = realParamsUrl + item + '?'
208
- }
209
- if (index !== 0 && index === (urlParts.length - 1)) {
210
- realParamsUrl = realParamsUrl + item
211
- }
212
- })
213
- console.log('realParamsUrl===========:', realParamsUrl)
214
- paramsUrl = realParamsUrl
215
- }
216
-
217
- paramsUrl = paramsUrl || '';
218
- var tmpWxYike = urlExt.getQuery('isWxYike', url); // 第二个参数如果为空,则自动从当前url中获取参数一的值
219
- if (Object.prototype.toString.call(tmpWxYike) === '[object Array]') {
220
- tmpWxYike = tmpWxYike[0];
221
- }
222
- var tmpSaleChannelId = urlExt.getQuery('saleChannelId', url);
223
- if (Object.prototype.toString.call(tmpSaleChannelId) === '[object Array]') {
224
- tmpSaleChannelId = tmpSaleChannelId[0];
225
- }
226
- var tmpLastFrom = urlExt.getQuery('lastfrom', url); // 第二个参数如果为空,则自动从当前url中获取参数一的值
227
- console.log('urlHandle-传入链接lastfrom的值为:', tmpLastFrom)
228
- if (Object.prototype.toString.call(tmpLastFrom) === '[object Array]') {
229
- tmpLastFrom = tmpLastFrom[0];
230
- }
231
- var tmpLogPath = urlExt.getQuery('logpath', url);
232
- if (Object.prototype.toString.call(tmpLogPath) === '[object Array]') {
233
- tmpLogPath = tmpLogPath[0];
234
- }
235
- var tmpFlowPond = urlExt.getQuery('flowPond', url);
236
- console.log('urlHandle-传入链接flowPond的值为:', tmpFlowPond)
237
- if (Object.prototype.toString.call(tmpFlowPond) === '[object Array]') {
238
- tmpFlowPond = tmpFlowPond[0];
239
- }
240
- var tmpOriFrom = urlExt.getQuery('orifrom', url) || urlExt.getQuery('fr', url);
241
- if (Object.prototype.toString.call(tmpOriFrom) === '[object Array]') {
242
- tmpOriFrom = tmpOriFrom[0];
243
- }
244
- if (!tmpWxYike) { // tmpWxYike,则将isWxYike拼在参数中
245
- paramsUrl = urlExt.setQuery('isWxYike', urlWxYike, paramsUrl);
246
- }
247
- if (!tmpSaleChannelId) { // tmpSaleChannelId,则将saleChannelId拼在参数中
248
- paramsUrl = urlExt.setQuery('saleChannelId', urlSaleChannelId, paramsUrl);
249
- }
250
- if (!tmpLastFrom) { // 如果tmpLastFrom为空,则将lastFrom拼在参数中
251
- paramsUrl = urlExt.setQuery('lastfrom', urlLastFrom, paramsUrl);
252
- }
253
- if (!tmpLogPath) { // 如果tmpLogPath空,则将urlLogPath拼在参数中
254
- paramsUrl = urlExt.setQuery('logpath', urlLogPath, paramsUrl);
255
- }
256
- // 用于处理url里面已有flowPond,同时需要merge当前页面设置的
257
- if (tmpFlowPond && isMerge) {
258
- paramsUrl = urlExt.setQuery('flowPond', mergeFlowPond(tmpFlowPond), paramsUrl);
259
- }
260
- if (!tmpFlowPond) {
261
- paramsUrl = urlExt.setQuery('flowPond', getUrlFlowPond(), paramsUrl);
262
- }
263
- if (Object.prototype.toString.call(urlOriFrom) === '[object Array]') {
264
- urlOriFrom = urlOriFrom[0];
265
- }
266
- if (urlOriFrom) { // 如果当前页的urlOriFrom不为空,则将fr拼进去
267
- paramsUrl = urlExt.setQuery('fr', urlOriFrom, paramsUrl);
268
- paramsUrl = urlExt.setQuery('orifrom', urlOriFrom, paramsUrl);
269
- } else { // 当前页的urlOriFrom为空
270
- paramsUrl = urlExt.setQuery('fr', tmpOriFrom, paramsUrl);
271
- paramsUrl = urlExt.setQuery('orifrom', tmpOriFrom, paramsUrl);
272
- }
273
- console.log('最后返回的链接:', normalUrl, paramsUrl)
274
- return normalUrl + '?' + paramsUrl;
275
- }
276
-
277
- // 在模块内隐式调用设置lastfrom
278
- setLastfrom(urlLastFrom);
279
-
280
- // 在模块内隐式调用设置fr
281
- setOriFrom(urlOriFrom);
282
-
283
- export default {
284
- getLogPath: getLogPath,
285
- setLogPath: setLogPath,
286
- getLastfrom: getLastfrom,
287
- setLastfrom: setLastfrom,
288
- getOriFrom: getOriFrom,
289
- setOriFrom: setOriFrom,
290
- urlHandle: urlHandle,
291
- setFlowPond: setFlowPond,
292
- getFlowPond: getFlowPond,
293
- getFlowPondKey: getFlowPondKey,
294
- getUrlFlowPond: getUrlFlowPond,
295
- resetFlowPond: resetFlowPond,
296
- resetLastfrom: resetLastfrom,
297
- resetOrifrom: resetOrifrom,
298
- }
@@ -1 +0,0 @@
1
- export default []
@@ -1,263 +0,0 @@
1
- <template>
2
- <div
3
- class="zyb-seckill"
4
- v-if="isShow"
5
- :style="bgStyle"
6
- >
7
- <div class="left-wrap">
8
- <div class="title" :style="titleFontStyle">
9
- <span class="icon"></span>{{titleText}}
10
- </div>
11
- <div
12
- class="num-wrap"
13
- :style="{
14
- backgroundColor: atmosphereBgColor
15
- }"
16
- >
17
- <div class="num" :style="atmosphereFontStyle">限量仅剩{{stock}}个名额</div>
18
- </div>
19
- </div>
20
- <div class="right-wrap">
21
- <div class="text">距秒杀结束还剩:</div>
22
- <div class="time">
23
- <div class="day" v-if="days">
24
- <span :style="formatGlyph(seckillStyle)">{{ days }}</span>天
25
- </div>
26
- <div class="t" :style="seckillFontStyle">{{ hours | formatTime }}</div>:
27
- <div class="t" :style="seckillFontStyle">{{ minutes | formatTime }}</div>:
28
- <div class="t" :style="seckillFontStyle">{{ secends | formatTime }}</div>
29
- </div>
30
- </div>
31
- </div>
32
- </template>
33
- <script lang="ts">
34
- import { Vue, Component, Prop, Watch, Mixins } from 'vue-property-decorator'
35
- import StickyMixin from '../../../lib/sticky-mixin'
36
- import { formatTimeArr } from '../../../lib/utils'
37
- import { service } from '../../../lib/request'
38
- const glyphObj = {
39
- 700: 'font-weight: 700;',
40
- italic: 'font-style: italic;',
41
- underline: 'text-decoration: underline;',
42
- 'line-through': 'text-decoration: line-through;'
43
- }
44
- @Component({
45
- name: 'QySeckill',
46
- filters: {
47
- formatTime (num: number) {
48
- return (num < 10 ? '0' : '') + num
49
- }
50
- }
51
- })
52
- export default class QySeckill extends Mixins(StickyMixin) {
53
- isEdit: any = process.env.VUE_APP_RUNTIME_PLATFORM === 'editor'
54
- // 秒杀主题文案:文案,字体36,颜色#141414,加粗
55
- @Prop({ type: String, default: '' }) titleText!: string
56
- @Prop({ type: [Number, String], default: 36 }) readonly titleSize!: number | string
57
- @Prop({ type: String, default: '#141414' }) readonly titleColor!: string
58
- @Prop({ type: Array, default: () => ['700'] }) readonly zybSeckillTitleStyle!: any
59
- get titleFontStyle () {
60
- return `color:${this.titleColor};font-size:${+this.titleSize /
61
- 100}rem;${this.formatGlyph(this.zybSeckillTitleStyle)};`
62
- }
63
- // 秒杀时间: 字体24,颜色FFFFFF
64
- @Prop({ type: Array, default: () => [new Date().getTime(), new Date().getTime() + 604800000] }) seckillDate!: []
65
- @Prop({ type: [Number, String], default: 24 }) readonly seckillSize!: number | string
66
- @Prop({ type: String, default: '#FFFFFF' }) readonly seckillColor!: string
67
- @Prop({ type: Array, default: () => [] }) readonly seckillStyle!:any
68
- get seckillFontStyle () {
69
- return `color:${this.seckillColor};font-size:${+this.seckillSize /
70
- 100}rem;${this.formatGlyph(this.seckillStyle)};`
71
- }
72
- // 氛围数据:字体24,颜色#FF6647,背景色#FF6E42
73
- @Prop({ type: [Number, String], default: 24 }) readonly atmosphereSize!: number | string
74
- @Prop({ type: String, default: '#FF6647' }) readonly atmosphereColor!: string
75
- @Prop({ type: Array, default: () => [] }) readonly atmosphereStyle!:any
76
- @Prop({ type: String, default: '#FF6E42' }) readonly atmosphereBgColor!: string
77
- get atmosphereFontStyle () {
78
- return `color:${this.atmosphereColor};font-size:${+this.atmosphereSize /
79
- 100}rem;${this.formatGlyph(this.atmosphereStyle)};`
80
- }
81
- // 图片列表
82
- @Prop({ type: Array, default: () => [{ imageUrl: '' }] }) readonly imageList!: Array<{ imageUrl: string }>
83
- get bgStyle () {
84
- return {
85
- backgroundImage: this.imageList[0].imageUrl ? `url(${this.imageList[0].imageUrl})` : null,
86
- backgroundRepeat: 'no-repeat',
87
- backgroundSize: '100% 100%'
88
- }
89
- }
90
- @Watch('seckillDate', { immediate: true })
91
- onDateChange (val: Array<Date>) {
92
- if (val) {
93
- this.startTime = new Date(val[0]).getTime()
94
- this.endTime = new Date(val[1]).getTime()
95
- } else {
96
- this.clearInterval()
97
- this.initTime()
98
- }
99
- }
100
- @Watch('endTime')
101
- onEndTimeChange () {
102
- this.clearInterval()
103
- this.setTimeInterval()
104
- }
105
- public formatGlyph (style: []) {
106
- return style
107
- .map((i: '700' | 'italic' | 'underline' | 'line-through') => glyphObj[i])
108
- .join('')
109
- }
110
- // 是否显示秒杀组件
111
- get isShow () {
112
- if (!this.isEdit && this.isEnd) {
113
- return false
114
- }
115
- return true
116
- }
117
-
118
- // 秒杀是否结束
119
- get isEnd () {
120
- return new Date().getTime() > this.endTime
121
- }
122
-
123
- startTime: number = 0
124
- endTime: number = 0
125
- days: number = 0
126
- hours: number = 0
127
- minutes: number = 0
128
- secends: number = 0
129
- timeOut: number = 0
130
- stock: number = 60
131
- private getStock () {
132
- if (!this.isEdit) {
133
- service({
134
- url: '/cube/api/random/stock',
135
- method: 'get'
136
- }).then((res: any) => {
137
- this.stock = res.data
138
- })
139
- }
140
- }
141
- created () {
142
- this.getTimeString()
143
- this.getStock()
144
- }
145
- mounted () {
146
- this.setTimeInterval()
147
- }
148
- destroyed () {
149
- this.clearInterval()
150
- }
151
- // 清除计时器
152
- public clearInterval () {
153
- if (this.timeOut) clearInterval(this.timeOut)
154
- }
155
- // 获取天、时、分、秒
156
- public getTimeString () {
157
- let nowTime = new Date().getTime()
158
- let timeArr = []
159
- if (this.isEnd) {
160
- timeArr = formatTimeArr(0)
161
- } else {
162
- timeArr = formatTimeArr(this.endTime - nowTime)
163
- }
164
- this.days = timeArr[0]
165
- this.hours = timeArr[1]
166
- this.minutes = timeArr[2]
167
- this.secends = timeArr[3]
168
- }
169
- public setTimeInterval () {
170
- this.timeOut = setInterval(() => {
171
- // this.showCount()
172
- if (this.isEnd) {
173
- this.clearInterval()
174
- this.initTime()
175
- return
176
- }
177
- this.getTimeString()
178
- }, 100) as any
179
- }
180
- public initTime () {
181
- this.days = 0
182
- this.hours = 0
183
- this.minutes = 0
184
- this.secends = 0
185
- }
186
- }
187
- </script>
188
- <style lang="less" scoped>
189
- .zyb-seckill {
190
- height: 1.4rem;
191
- display: flex;
192
- background-color: #FFF7F6;
193
- .left-wrap {
194
- min-width: 4.42rem;
195
- padding-left: 0.32rem;
196
- .title {
197
- height: 0.36rem;
198
- margin: 0.26rem 0 0.14rem;
199
- font-size: 0.36rem;
200
- line-height: 0.36rem;
201
- display: flex;
202
- align-items: center;
203
- .icon {
204
- display: inline-block;
205
- height: 0.36rem;
206
- width: 0.36rem;
207
- margin-right: 0.15rem;
208
- background-size: 100% 100%;
209
- background-image: url(./../static/clock.png);
210
- }
211
- }
212
- .num-wrap {
213
- height: 0.34rem;
214
- width: 3.2rem;
215
- border-radius: 0.18rem;
216
- .num {
217
- width: 2.52rem;
218
- height: 0.34rem;
219
- display: flex;
220
- align-items: center;
221
- justify-content: center;
222
- margin-right: auto;
223
- background-color: #FFFDE1;
224
- border-radius: 0.18rem 0px 0px 0.18rem;
225
- //
226
- font-weight: 600;
227
- }
228
- }
229
- }
230
- .right-wrap {
231
- flex-grow: 1;
232
- .text {
233
- height: 0.24rem;
234
- line-height: 0.24rem;
235
- margin: 0.26rem 0 0.24rem;
236
- text-align: center;
237
- color: #FF6647;
238
- font-size: 0.24rem;
239
- }
240
- .time {
241
- height: 0.4rem;
242
- display: flex;
243
- align-items: center;
244
- justify-content: center;
245
- color: #FF6647;
246
- font-size: 0.24rem;
247
- .t {
248
- display: inline-flex;
249
- height: 0.4rem;
250
- width: 0.4rem;
251
- margin: 0 0.08rem;
252
- border-radius: 0.04rem;
253
- background-color: #FF3B00;
254
- align-items: center;
255
- justify-content: center;
256
- color: #FFFFFF;
257
- font-size: 0.26rem;
258
- font-weight: 500;
259
- }
260
- }
261
- }
262
- }
263
- </style>
@@ -1,18 +0,0 @@
1
- import Vue, { VueConstructor } from 'vue'
2
- import QySeckill from './components/index.vue'
3
- import Settings from './settings'
4
- import Actions from './actions'
5
- import Menu from './menu'
6
-
7
- const install = (Vue: VueConstructor<Vue>, options: any) => {
8
- Vue.component(QySeckill.name, QySeckill)
9
- }
10
-
11
- export default {
12
- install,
13
- name: QySeckill.name,
14
- component: QySeckill,
15
- settings: Settings,
16
- actions: Actions,
17
- menu: Menu
18
- }
@@ -1,6 +0,0 @@
1
- export default {
2
- title: '秒杀',
3
- type: 'atmosphere',
4
- name: 'QySeckill',
5
- icon: 'icon_countdown'
6
- }