33 changed files with 28437 additions and 23 deletions
@ -0,0 +1,2 @@ |
|||||
|
NODE_ENV = 'production' |
||||
|
VUE_APP_FLAG = 'pro' |
||||
@ -0,0 +1,2 @@ |
|||||
|
NODE_ENV = 'production' |
||||
|
VUE_APP_FLAG = 'test' |
||||
@ -1,25 +1,23 @@ |
|||||
# ---> Java |
.DS_Store |
||||
# Compiled class file |
node_modules |
||||
*.class |
/dist |
||||
|
|
||||
# Log file |
|
||||
*.log |
|
||||
|
|
||||
# BlueJ files |
# local env files |
||||
*.ctxt |
.env.local |
||||
|
.env.*.local |
||||
|
|
||||
# Mobile Tools for Java (J2ME) |
# Log files |
||||
.mtj.tmp/ |
npm-debug.log* |
||||
|
yarn-debug.log* |
||||
# Package Files # |
yarn-error.log* |
||||
*.jar |
pnpm-debug.log* |
||||
*.war |
|
||||
*.nar |
|
||||
*.ear |
|
||||
*.zip |
|
||||
*.tar.gz |
|
||||
*.rar |
|
||||
|
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml |
|
||||
hs_err_pid* |
|
||||
|
|
||||
|
# Editor directories and files |
||||
|
.idea |
||||
|
.vscode |
||||
|
*.suo |
||||
|
*.ntvs* |
||||
|
*.njsproj |
||||
|
*.sln |
||||
|
*.sw? |
||||
|
|||||
@ -1,3 +1,29 @@ |
|||||
# rights-front |
# my-project |
||||
|
|
||||
会员权益前端 |
## Project setup |
||||
|
``` |
||||
|
npm install |
||||
|
``` |
||||
|
|
||||
|
### Compiles and hot-reloads for development |
||||
|
``` |
||||
|
npm run serve |
||||
|
``` |
||||
|
|
||||
|
### Compiles and minifies for production |
||||
|
``` |
||||
|
npm run build |
||||
|
``` |
||||
|
|
||||
|
### Run your tests |
||||
|
``` |
||||
|
npm run test |
||||
|
``` |
||||
|
|
||||
|
### Lints and fixes files |
||||
|
``` |
||||
|
npm run lint |
||||
|
``` |
||||
|
|
||||
|
### Customize configuration |
||||
|
See [Configuration Reference](https://cli.vuejs.org/config/). |
||||
|
|||||
@ -0,0 +1,5 @@ |
|||||
|
module.exports = { |
||||
|
presets: [ |
||||
|
'@vue/cli-plugin-babel/preset' |
||||
|
] |
||||
|
} |
||||
File diff suppressed because it is too large
@ -0,0 +1,53 @@ |
|||||
|
{ |
||||
|
"name": "my-project", |
||||
|
"version": "0.1.0", |
||||
|
"private": true, |
||||
|
"scripts": { |
||||
|
"serve": "vue-cli-service serve", |
||||
|
"build": "vue-cli-service build", |
||||
|
"start": "yarn run serve", |
||||
|
"test": "yarn run serve --mode test", |
||||
|
"build:sit": "vue-cli-service build --mode test" |
||||
|
}, |
||||
|
"dependencies": { |
||||
|
"@lucky-canvas/vue": "^0.1.11", |
||||
|
"axios": "^0.21.1", |
||||
|
"compression-webpack-plugin": "5.0.1", |
||||
|
"core-js": "^3.6.5", |
||||
|
"crypto-js": "^4.1.1", |
||||
|
"enc": "^0.4.0", |
||||
|
"js-md5": "^0.7.3", |
||||
|
"mint-ui": "^2.2.13", |
||||
|
"node-sass": "^4.12.0", |
||||
|
"sockjs-client": "^1.6.1", |
||||
|
"stompjs": "^2.3.3", |
||||
|
"swiper": "^8.4.4", |
||||
|
"vant": "^4.0.10", |
||||
|
"vue": "^2.6.11", |
||||
|
"vue-awesome-swiper": "^3.1.3", |
||||
|
"vue-axios": "^3.2.4", |
||||
|
"vue-lazyload": "^1.3.3", |
||||
|
"vue-monoplasty-slide-verify": "^1.3.1", |
||||
|
"vue-router": "^3.2.0", |
||||
|
"vue-seamless-scroll": "^1.1.23" |
||||
|
}, |
||||
|
"devDependencies": { |
||||
|
"@vue/cli-plugin-babel": "^4.5.0", |
||||
|
"@vue/cli-service": "^4.5.0", |
||||
|
"babel-plugin-component": "^1.1.1", |
||||
|
"sass-loader": "^8.0.2", |
||||
|
"vue-cookie": "^1.1.4", |
||||
|
"vue-template-compiler": "^2.6.11", |
||||
|
"worker-loader": "2.0.0" |
||||
|
}, |
||||
|
"browserslist": [ |
||||
|
"> 1%", |
||||
|
"last 2 versions", |
||||
|
"not dead" |
||||
|
], |
||||
|
"description": "## Project setup ``` npm install ```", |
||||
|
"main": "babel.config.js", |
||||
|
"keywords": [], |
||||
|
"author": "dongdada", |
||||
|
"license": "ISC" |
||||
|
} |
||||
|
After Width: | Height: | Size: 4.2 KiB |
@ -0,0 +1,73 @@ |
|||||
|
<!DOCTYPE html> |
||||
|
<html lang=""> |
||||
|
<head> |
||||
|
<meta charset="utf-8"> |
||||
|
<meta http-equiv="X-UA-Compatible" content="pc,mobile"> |
||||
|
<meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no,minimum-scale=1,maximum-scale=1"> |
||||
|
<link rel="icon" href="<%= BASE_URL %>favicon.ico"> |
||||
|
<title></title> |
||||
|
<style> |
||||
|
.mint-indicator-wrapper { |
||||
|
z-index: 1000 !important; |
||||
|
} |
||||
|
.mint-indicator-mask { |
||||
|
z-index: 1000 !important; |
||||
|
} |
||||
|
</style> |
||||
|
|
||||
|
</head> |
||||
|
<body id="body" style="visibility: hidden;"> |
||||
|
|
||||
|
<div id="app"></div> |
||||
|
</body> |
||||
|
|
||||
|
<!-- vconsole --> |
||||
|
<!-- <script src="https://unpkg.com/vconsole/dist/vconsole.min.js"></script> |
||||
|
<script> |
||||
|
// VConsole will be exported to `window.VConsole` by default. |
||||
|
var vConsole = new window.VConsole(); |
||||
|
</script> --> |
||||
|
|
||||
|
|
||||
|
</html> |
||||
|
<script> |
||||
|
|
||||
|
window._gr_ignore_local_rule=true; |
||||
|
(function(window,document,script,src,namespace){ |
||||
|
window[namespace] = window[namespace] || function(){ |
||||
|
(window[namespace].q = window[namespace].q || []).push(arguments) |
||||
|
}; |
||||
|
script = document.createElement('script'); |
||||
|
let tag = document.getElementsByTagName('script')[0]; |
||||
|
script.async = true; |
||||
|
script.src = src; |
||||
|
tag.parentNode.insertBefore(script,tag); |
||||
|
})(window,document,"script","https://assets.giocdn.com/sdk/cdp/gio.js","gdp") |
||||
|
|
||||
|
|
||||
|
function aa(){ |
||||
|
(function (doc, win) { |
||||
|
var docEl = doc.documentElement, |
||||
|
bodys = document.getElementsByTagName('body')[0], |
||||
|
resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize', |
||||
|
recalc = function () { |
||||
|
var clientWidth = docEl.clientWidth; |
||||
|
if (!clientWidth) return; |
||||
|
docEl.style.fontSize = 100 * (clientWidth / 750) + 'px'; |
||||
|
bodys.style.visibility = 'visible'; |
||||
|
}; |
||||
|
if (!doc.addEventListener) return; |
||||
|
win.addEventListener(resizeEvt, recalc, false); |
||||
|
doc.addEventListener('DOMContentLoaded', recalc, false); |
||||
|
})(document, window); |
||||
|
}; |
||||
|
if (/Android|webOS|iPhone|iPod|BlackBerry/i.test(navigator.userAgent)) { |
||||
|
aa(); |
||||
|
} else { |
||||
|
bodys = document.getElementsByTagName('body')[0]; |
||||
|
bodys.style.visibility = 'visible'; |
||||
|
document.getElementsByTagName("html")[0].style.fontSize = "104px"; |
||||
|
document.getElementsByTagName("body")[0].style.width = "750px"; |
||||
|
document.getElementsByTagName("body")[0].style.margin = "0 auto"; |
||||
|
} |
||||
|
</script> |
||||
@ -0,0 +1,31 @@ |
|||||
|
<template> |
||||
|
<div id="app"> |
||||
|
<router-view v-if="isRouterAlive" /> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script> |
||||
|
export default { |
||||
|
provide() { |
||||
|
return { |
||||
|
reload: this.reload, |
||||
|
}; |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
isRouterAlive: true, |
||||
|
}; |
||||
|
}, |
||||
|
|
||||
|
methods: { |
||||
|
reload() { |
||||
|
this.isRouterAlive = false; |
||||
|
this.$nextTick(function () { |
||||
|
this.isRouterAlive = true; |
||||
|
}); |
||||
|
}, |
||||
|
} |
||||
|
}; |
||||
|
</script> |
||||
|
<style lang="scss"> |
||||
|
@import "./assets/scss/reset.scss"; |
||||
|
</style> |
||||
File diff suppressed because it is too large
@ -0,0 +1,140 @@ |
|||||
|
// import store from '@/store'
|
||||
|
// import { Message } from 'element-ui'
|
||||
|
import {Indicator, Toast} from "mint-ui"; |
||||
|
|
||||
|
var url = 'ws://192.168.1.6:8081/simple/' |
||||
|
var ws; |
||||
|
var tt; |
||||
|
var lockReconnect = false;//避免重复连接
|
||||
|
var clientId = localStorage.getItem("clientId")//缓存中取出客户端id
|
||||
|
|
||||
|
var websocket = { |
||||
|
Init: function(clientId) { |
||||
|
if ("WebSocket" in window) { |
||||
|
ws = new WebSocket(url + clientId); |
||||
|
} else if ("MozWebSocket" in window) { |
||||
|
ws = new MozWebSocket(url + clientId); |
||||
|
} else { |
||||
|
console.log("您的浏览器不支持 WebSocket!"); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
ws.onmessage = function(e) { |
||||
|
console.log("接收消息:" + e.data) |
||||
|
heartCheck.start() |
||||
|
if(e.data=='ok'){//心跳消息不做处理
|
||||
|
return |
||||
|
} |
||||
|
//messageHandle(e.data)
|
||||
|
} |
||||
|
|
||||
|
ws.onclose = function() { |
||||
|
console.log("连接已关闭") |
||||
|
Toast({ |
||||
|
message: '连接已关闭', |
||||
|
type: 'error', |
||||
|
}); |
||||
|
reconnect(clientId); |
||||
|
} |
||||
|
|
||||
|
ws.onopen = function() { |
||||
|
console.log("连接成功") |
||||
|
Toast({ |
||||
|
message: '连接成功', |
||||
|
type: 'success', |
||||
|
}); |
||||
|
heartCheck.start(); |
||||
|
} |
||||
|
|
||||
|
ws.onerror = function(e) { |
||||
|
console.log("数据传输发生错误"); |
||||
|
Toast({ |
||||
|
message: '数据传输发生错误', |
||||
|
type: 'error', |
||||
|
}); |
||||
|
reconnect(clientId) |
||||
|
} |
||||
|
}, |
||||
|
Send:function(sender,reception,body,flag){ |
||||
|
let data = { |
||||
|
sender:sender, |
||||
|
reception:reception, |
||||
|
body:body, |
||||
|
flag:flag |
||||
|
} |
||||
|
let msg= JSON.stringify(data) |
||||
|
console.log("发送消息:"+msg) |
||||
|
ws.send(msg) |
||||
|
}, |
||||
|
getWebSocket(){ |
||||
|
return ws; |
||||
|
}, |
||||
|
getStatus() { |
||||
|
if (ws.readyState == 0) { |
||||
|
return "未连接"; |
||||
|
} else if (ws.readyState == 1) { |
||||
|
return "已连接"; |
||||
|
} else if (ws.readyState == 2) { |
||||
|
return "连接正在关闭"; |
||||
|
} else if (ws.readyState == 3) { |
||||
|
return "连接已关闭"; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
export default websocket; |
||||
|
|
||||
|
//根据消息标识做不同的处理
|
||||
|
function messageHandle(message) { |
||||
|
let msg = JSON.parse(message) |
||||
|
switch (msg.flag) { |
||||
|
case 'command': |
||||
|
console.log("指令消息类型") |
||||
|
break; |
||||
|
case 'inform': |
||||
|
console.log("通知") |
||||
|
break; |
||||
|
default: |
||||
|
console.log("未知消息类型") |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function reconnect(sname) { |
||||
|
if(lockReconnect) { |
||||
|
return; |
||||
|
}; |
||||
|
lockReconnect = true; |
||||
|
//没连接上会一直重连,设置延迟避免请求过多
|
||||
|
tt && clearTimeout(tt); |
||||
|
tt = setTimeout(function () { |
||||
|
console.log("执行断线重连...") |
||||
|
websocket.Init(sname); |
||||
|
lockReconnect = false; |
||||
|
}, 4000); |
||||
|
} |
||||
|
|
||||
|
//心跳检测
|
||||
|
var heartCheck = { |
||||
|
timeout: 1000 * 60 * 3, |
||||
|
timeoutObj: null, |
||||
|
serverTimeoutObj: null, |
||||
|
start: function(){ |
||||
|
console.log('开始心跳检测'); |
||||
|
var self = this; |
||||
|
this.timeoutObj && clearTimeout(this.timeoutObj); |
||||
|
this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj); |
||||
|
this.timeoutObj = setTimeout(function(){ |
||||
|
//这里发送一个心跳,后端收到后,返回一个心跳消息,
|
||||
|
//onmessage拿到返回的心跳就说明连接正常
|
||||
|
console.log('心跳检测...'); |
||||
|
ws.send("HeartBeat:"+ clientId ); |
||||
|
self.serverTimeoutObj = setTimeout(function() { |
||||
|
if(ws.readyState!=1){ |
||||
|
ws.close(); |
||||
|
} |
||||
|
// createWebSocket();
|
||||
|
}, self.timeout); |
||||
|
|
||||
|
}, this.timeout) |
||||
|
} |
||||
|
} |
||||
File diff suppressed because one or more lines are too long
@ -0,0 +1,318 @@ |
|||||
|
/* |
||||
|
* @Autor: lycheng |
||||
|
* @Date: 2020-01-13 16:12:22 |
||||
|
*/ |
||||
|
/** |
||||
|
* Created by iflytek on 2019/11/19. |
||||
|
* |
||||
|
* 在线语音合成调用demo |
||||
|
* 此demo只是一个简单的调用示例,不适合用到实际生产环境中 |
||||
|
* |
||||
|
* 在线语音合成 WebAPI 接口调用示例 接口文档(必看):https://www.xfyun.cn/doc/tts/online_tts/API.html
|
||||
|
* 错误码链接: |
||||
|
* https://www.xfyun.cn/doc/tts/online_tts/API.html
|
||||
|
* https://www.xfyun.cn/document/error-code (code返回错误码时必看)
|
||||
|
* |
||||
|
*/ |
||||
|
|
||||
|
// 1. websocket连接:判断浏览器是否兼容,获取websocket url并连接,这里为了方便本地生成websocket url
|
||||
|
// 2. 连接websocket,向websocket发送数据,实时接收websocket返回数据
|
||||
|
// 3. 处理websocket返回数据为浏览器可以播放的音频数据
|
||||
|
// 4. 播放音频数据
|
||||
|
// ps: 该示例用到了es6中的一些语法,建议在chrome下运行
|
||||
|
// import {downloadPCM, downloadWAV} from 'js/download.js'
|
||||
|
import CryptoJS from 'crypto-js' |
||||
|
import Enc from 'enc' |
||||
|
import TransWorker from '@/assets/js/speechSynthesis/transcode.worker' |
||||
|
// import VConsole from 'vconsole'
|
||||
|
import { Base64 } from 'js-base64' |
||||
|
// import './index.css'
|
||||
|
|
||||
|
let transWorker = new TransWorker() |
||||
|
//APPID,APISecret,APIKey在控制台-我的应用-语音合成(流式版)页面获取
|
||||
|
const APPID = 'a5d29f72' |
||||
|
const API_SECRET = 'YmNkNjU4ODU4YzAzN2U1OTgwZGE3OWFh' |
||||
|
const API_KEY = 'c7c9a5cf79824ccfed2dd55acd49bf53' |
||||
|
|
||||
|
function getWebsocketUrl() { |
||||
|
return new Promise((resolve, reject) => { |
||||
|
var apiKey = API_KEY |
||||
|
var apiSecret = API_SECRET |
||||
|
var url = 'wss://tts-api.xfyun.cn/v2/tts' |
||||
|
var host = location.host |
||||
|
var date = new Date().toGMTString() |
||||
|
var algorithm = 'hmac-sha256' |
||||
|
var headers = 'host date request-line' |
||||
|
var signatureOrigin = `host: ${host}\ndate: ${date}\nGET /v2/tts HTTP/1.1` |
||||
|
var signatureSha = CryptoJS.HmacSHA256(signatureOrigin, apiSecret) |
||||
|
var signature = CryptoJS.enc.Base64.stringify(signatureSha) |
||||
|
var authorizationOrigin = `api_key="${apiKey}", algorithm="${algorithm}", headers="${headers}", signature="${signature}"` |
||||
|
var authorization = btoa(authorizationOrigin) |
||||
|
url = `${url}?authorization=${authorization}&date=${date}&host=${host}` |
||||
|
resolve(url) |
||||
|
}) |
||||
|
} |
||||
|
const TTSRecorder =class { |
||||
|
constructor({ |
||||
|
speed = 30, |
||||
|
voice = 50, |
||||
|
pitch = 50, |
||||
|
voiceName = 'aisjiuxu', |
||||
|
appId = APPID, |
||||
|
text = '', |
||||
|
tte = 'UTF8', |
||||
|
defaultText = '请输入您要合成的文本', |
||||
|
} = {}) { |
||||
|
this.speed = speed |
||||
|
this.voice = voice |
||||
|
this.pitch = pitch |
||||
|
this.voiceName = voiceName |
||||
|
this.text = text |
||||
|
this.tte = tte |
||||
|
this.defaultText = defaultText |
||||
|
this.appId = appId |
||||
|
this.audioData = [] |
||||
|
this.rawAudioData = [] |
||||
|
this.audioDataOffset = 0 |
||||
|
this.status = 'init' |
||||
|
transWorker.onmessage = (e) => { |
||||
|
this.audioData.push(...e.data.data) |
||||
|
this.rawAudioData.push(...e.data.rawAudioData) |
||||
|
} |
||||
|
} |
||||
|
// 修改录音听写状态
|
||||
|
setStatus(status) { |
||||
|
this.onWillStatusChange && this.onWillStatusChange(this.status, status) |
||||
|
this.status = status |
||||
|
} |
||||
|
|
||||
|
// 设置合成相关参数
|
||||
|
setParams({ speed, voice, pitch, text, voiceName, tte }) { |
||||
|
speed !== undefined && (this.speed = speed) |
||||
|
voice !== undefined && (this.voice = voice) |
||||
|
pitch !== undefined && (this.pitch = pitch) |
||||
|
text && (this.text = text) |
||||
|
tte && (this.tte = tte) |
||||
|
voiceName && (this.voiceName = voiceName) |
||||
|
this.resetAudio() |
||||
|
} |
||||
|
// 连接websocket
|
||||
|
connectWebSocket() { |
||||
|
this.setStatus('ttsing') |
||||
|
return getWebsocketUrl().then(url => { |
||||
|
let ttsWS |
||||
|
if ('WebSocket' in window) { |
||||
|
ttsWS = new WebSocket(url) |
||||
|
} else if ('MozWebSocket' in window) { |
||||
|
ttsWS = new MozWebSocket(url) |
||||
|
} else { |
||||
|
alert('浏览器不支持WebSocket') |
||||
|
return |
||||
|
} |
||||
|
this.ttsWS = ttsWS |
||||
|
ttsWS.onopen = e => { |
||||
|
this.webSocketSend() |
||||
|
this.playTimeout = setTimeout(() => { |
||||
|
this.audioPlay() |
||||
|
}, 1000) |
||||
|
} |
||||
|
ttsWS.onmessage = e => { |
||||
|
this.result(e.data) |
||||
|
} |
||||
|
ttsWS.onerror = e => { |
||||
|
clearTimeout(this.playTimeout) |
||||
|
this.setStatus('errorTTS') |
||||
|
alert('WebSocket报错,请f12查看详情') |
||||
|
console.error(`详情查看:${encodeURI(url.replace('wss:', 'https:'))}`) |
||||
|
} |
||||
|
ttsWS.onclose = e => { |
||||
|
// console.log(e)
|
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
// 处理音频数据
|
||||
|
transToAudioData(audioData) {} |
||||
|
// websocket发送数据
|
||||
|
webSocketSend() { |
||||
|
var params = { |
||||
|
common: { |
||||
|
app_id: this.appId, // APPID
|
||||
|
}, |
||||
|
business: { |
||||
|
aue: 'raw', |
||||
|
// sfl= 1,
|
||||
|
auf: 'audio/L16;rate=16000', |
||||
|
vcn: this.voiceName, |
||||
|
speed: this.speed, |
||||
|
volume: this.voice, |
||||
|
pitch: this.pitch, |
||||
|
bgs: 1, |
||||
|
tte: this.tte, |
||||
|
}, |
||||
|
data: { |
||||
|
status: 2, |
||||
|
text: this.encodeText( |
||||
|
this.text || this.defaultText, |
||||
|
this.tte === 'unicode' ? 'base64&utf16le' : '' |
||||
|
) |
||||
|
}, |
||||
|
} |
||||
|
this.ttsWS.send(JSON.stringify(params)) |
||||
|
} |
||||
|
encodeText (text, encoding) { |
||||
|
switch (encoding) { |
||||
|
case 'utf16le' : { |
||||
|
let buf = new ArrayBuffer(text.length * 4) |
||||
|
let bufView = new Uint16Array(buf) |
||||
|
for (let i = 0, strlen = text.length; i < strlen; i++) { |
||||
|
bufView[i] = text.charCodeAt(i) |
||||
|
} |
||||
|
return buf |
||||
|
} |
||||
|
case 'buffer2Base64': { |
||||
|
let binary = '' |
||||
|
let bytes = new Uint8Array(text) |
||||
|
let len = bytes.byteLength |
||||
|
for (let i = 0; i < len; i++) { |
||||
|
binary += String.fromCharCode(bytes[i]) |
||||
|
} |
||||
|
return window.btoa(binary) |
||||
|
} |
||||
|
case 'base64&utf16le' : { |
||||
|
return this.encodeText(this.encodeText(text, 'utf16le'), 'buffer2Base64') |
||||
|
} |
||||
|
default : { |
||||
|
return Base64.encode(text) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
// websocket接收数据的处理
|
||||
|
result(resultData) { |
||||
|
let jsonData = JSON.parse(resultData) |
||||
|
// 合成失败
|
||||
|
if (jsonData.code !== 0) { |
||||
|
alert(`合成失败: ${jsonData.code}:${jsonData.message}`) |
||||
|
console.error(`${jsonData.code}:${jsonData.message}`) |
||||
|
this.resetAudio() |
||||
|
return |
||||
|
} |
||||
|
transWorker.postMessage(jsonData.data.audio) |
||||
|
|
||||
|
if (jsonData.code === 0 && jsonData.data.status === 2) { |
||||
|
this.ttsWS.close() |
||||
|
} |
||||
|
} |
||||
|
// 重置音频数据
|
||||
|
resetAudio() { |
||||
|
this.audioStop() |
||||
|
this.setStatus('init') |
||||
|
this.audioDataOffset = 0 |
||||
|
this.audioData = [] |
||||
|
this.rawAudioData = [] |
||||
|
this.ttsWS && this.ttsWS.close() |
||||
|
clearTimeout(this.playTimeout) |
||||
|
} |
||||
|
// 音频初始化
|
||||
|
audioInit() { |
||||
|
let AudioContext = window.AudioContext || window.webkitAudioContext |
||||
|
if (AudioContext) { |
||||
|
this.audioContext = new AudioContext() |
||||
|
this.audioContext.resume() |
||||
|
this.audioDataOffset = 0 |
||||
|
} |
||||
|
} |
||||
|
// 音频播放
|
||||
|
audioPlay() { |
||||
|
this.setStatus('play') |
||||
|
let audioData = this.audioData.slice(this.audioDataOffset) |
||||
|
this.audioDataOffset += audioData.length |
||||
|
let audioBuffer = this.audioContext.createBuffer(1, audioData.length, 22050) |
||||
|
let nowBuffering = audioBuffer.getChannelData(0) |
||||
|
if (audioBuffer.copyToChannel) { |
||||
|
audioBuffer.copyToChannel(new Float32Array(audioData), 0, 0) |
||||
|
} else { |
||||
|
for (let i = 0; i < audioData.length; i++) { |
||||
|
nowBuffering[i] = audioData[i] |
||||
|
} |
||||
|
} |
||||
|
let bufferSource = this.bufferSource = this.audioContext.createBufferSource() |
||||
|
bufferSource.buffer = audioBuffer |
||||
|
bufferSource.connect(this.audioContext.destination) |
||||
|
bufferSource.start() |
||||
|
bufferSource.onended = event => { |
||||
|
if (this.status !== 'play') { |
||||
|
return |
||||
|
} |
||||
|
if (this.audioDataOffset < this.audioData.length) { |
||||
|
this.audioPlay() |
||||
|
} else { |
||||
|
this.audioStop() |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
// 音频播放结束
|
||||
|
audioStop() { |
||||
|
this.setStatus('endPlay') |
||||
|
clearTimeout(this.playTimeout) |
||||
|
this.audioDataOffset = 0 |
||||
|
if (this.bufferSource) { |
||||
|
try { |
||||
|
this.bufferSource.stop() |
||||
|
} catch (e) { |
||||
|
// console.log(e)
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
start() { |
||||
|
if(this.audioData.length) { |
||||
|
this.audioPlay() |
||||
|
} else { |
||||
|
if (!this.audioContext) { |
||||
|
this.audioInit() |
||||
|
} |
||||
|
if (!this.audioContext) { |
||||
|
alert('该浏览器不支持webAudioApi相关接口') |
||||
|
return |
||||
|
} |
||||
|
this.connectWebSocket() |
||||
|
} |
||||
|
} |
||||
|
stop() { |
||||
|
this.audioStop() |
||||
|
} |
||||
|
} |
||||
|
export default TTSRecorder |
||||
|
// ======================开始调用=============================
|
||||
|
// var vConsole = new VConsole()
|
||||
|
// let ttsRecorder = new TTSRecorder()
|
||||
|
// ttsRecorder.onWillStatusChange = function(oldStatus, status) {
|
||||
|
// // 可以在这里进行页面中一些交互逻辑处理:按钮交互等
|
||||
|
// // 按钮中的文字
|
||||
|
// let btnState = {
|
||||
|
// init: '立即合成',
|
||||
|
// ttsing: '正在合成',
|
||||
|
// play: '停止播放',
|
||||
|
// endPlay: '重新播放',
|
||||
|
// errorTTS: '合成失败',
|
||||
|
// }
|
||||
|
// $('.audio-ctrl-btn')
|
||||
|
// .removeClass(oldStatus)
|
||||
|
// .addClass(status)
|
||||
|
// .text(btnState[status])
|
||||
|
// }
|
||||
|
|
||||
|
|
||||
|
// $('.audio-ctrl-btn').click(function() {
|
||||
|
// if (['init', 'endPlay', 'errorTTS'].indexOf(ttsRecorder.status) > -1) {
|
||||
|
// ttsRecorder.start()
|
||||
|
// } else {
|
||||
|
// ttsRecorder.stop()
|
||||
|
// }
|
||||
|
// })
|
||||
|
|
||||
|
|
||||
|
// $('#input_text').change(function(){
|
||||
|
// ttsRecorder.setParams({
|
||||
|
// text: this.value
|
||||
|
// })
|
||||
|
// })
|
||||
@ -0,0 +1,53 @@ |
|||||
|
/* |
||||
|
* @Autor: lycheng |
||||
|
* @Date: 2020-01-13 16:12:22 |
||||
|
*/ |
||||
|
(function(){ |
||||
|
let minSampleRate = 22050 |
||||
|
self.onmessage = function(e) { |
||||
|
transcode.transToAudioData(e.data) |
||||
|
} |
||||
|
var transcode = { |
||||
|
transToAudioData: function(audioDataStr, fromRate = 16000, toRate = 22505) { |
||||
|
let outputS16 = transcode.base64ToS16(audioDataStr) |
||||
|
let output = transcode.transS16ToF32(outputS16) |
||||
|
output = transcode.transSamplingRate(output, fromRate, toRate) |
||||
|
output = Array.from(output) |
||||
|
self.postMessage({ |
||||
|
data: output, |
||||
|
rawAudioData: Array.from(outputS16) |
||||
|
}) |
||||
|
}, |
||||
|
transSamplingRate: function(data, fromRate = 44100, toRate = 16000) { |
||||
|
var fitCount = Math.round(data.length * (toRate / fromRate)) |
||||
|
var newData = new Float32Array(fitCount) |
||||
|
var springFactor = (data.length - 1) / (fitCount - 1) |
||||
|
newData[0] = data[0] |
||||
|
for (let i = 1; i < fitCount - 1; i++) { |
||||
|
var tmp = i * springFactor |
||||
|
var before = Math.floor(tmp).toFixed() |
||||
|
var after = Math.ceil(tmp).toFixed() |
||||
|
var atPoint = tmp - before |
||||
|
newData[i] = data[before] + (data[after] - data[before]) * atPoint |
||||
|
} |
||||
|
newData[fitCount - 1] = data[data.length - 1] |
||||
|
return newData |
||||
|
}, |
||||
|
transS16ToF32: function(input) { |
||||
|
var tmpData = [] |
||||
|
for (let i = 0; i < input.length; i++) { |
||||
|
var d = input[i] < 0 ? input[i] / 0x8000 : input[i] / 0x7fff |
||||
|
tmpData.push(d) |
||||
|
} |
||||
|
return new Float32Array(tmpData) |
||||
|
}, |
||||
|
base64ToS16: function(base64AudioData) { |
||||
|
base64AudioData = atob(base64AudioData) |
||||
|
const outputArray = new Uint8Array(base64AudioData.length) |
||||
|
for (let i = 0; i < base64AudioData.length; ++i) { |
||||
|
outputArray[i] = base64AudioData.charCodeAt(i) |
||||
|
} |
||||
|
return new Int16Array(new DataView(outputArray.buffer).buffer) |
||||
|
}, |
||||
|
} |
||||
|
})() |
||||
@ -0,0 +1,501 @@ |
|||||
|
// Generated by CoffeeScript 1.7.1
|
||||
|
|
||||
|
/* |
||||
|
Stomp Over WebSocket http://www.jmesnil.net/stomp-websocket/doc/ | Apache License V2.0
|
||||
|
|
||||
|
Copyright (C) 2010-2013 [Jeff Mesnil](http://jmesnil.net/)
|
||||
|
Copyright (C) 2012 [FuseSource, Inc.](http://fusesource.com)
|
||||
|
*/ |
||||
|
|
||||
|
(function() { |
||||
|
var Byte, Client, Frame, Stomp, |
||||
|
__hasProp = {}.hasOwnProperty, |
||||
|
__slice = [].slice; |
||||
|
|
||||
|
Byte = { |
||||
|
LF: '\x0A', |
||||
|
NULL: '\x00' |
||||
|
}; |
||||
|
|
||||
|
Frame = (function() { |
||||
|
var unmarshallSingle; |
||||
|
|
||||
|
function Frame(command, headers, body) { |
||||
|
this.command = command; |
||||
|
this.headers = headers != null ? headers : {}; |
||||
|
this.body = body != null ? body : ''; |
||||
|
} |
||||
|
|
||||
|
Frame.prototype.toString = function() { |
||||
|
var lines, name, skipContentLength, value, _ref; |
||||
|
lines = [this.command]; |
||||
|
skipContentLength = this.headers['content-length'] === false ? true : false; |
||||
|
if (skipContentLength) { |
||||
|
delete this.headers['content-length']; |
||||
|
} |
||||
|
_ref = this.headers; |
||||
|
for (name in _ref) { |
||||
|
if (!__hasProp.call(_ref, name)) continue; |
||||
|
value = _ref[name]; |
||||
|
lines.push("" + name + ":" + value); |
||||
|
} |
||||
|
if (this.body && !skipContentLength) { |
||||
|
lines.push("content-length:" + (Frame.sizeOfUTF8(this.body))); |
||||
|
} |
||||
|
lines.push(Byte.LF + this.body); |
||||
|
return lines.join(Byte.LF); |
||||
|
}; |
||||
|
|
||||
|
Frame.sizeOfUTF8 = function(s) { |
||||
|
if (s) { |
||||
|
return encodeURI(s).match(/%..|./g).length; |
||||
|
} else { |
||||
|
return 0; |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
unmarshallSingle = function(data) { |
||||
|
var body, chr, command, divider, headerLines, headers, i, idx, len, line, start, trim, _i, _j, _len, _ref, _ref1; |
||||
|
divider = data.search(RegExp("" + Byte.LF + Byte.LF)); |
||||
|
headerLines = data.substring(0, divider).split(Byte.LF); |
||||
|
command = headerLines.shift(); |
||||
|
headers = {}; |
||||
|
trim = function(str) { |
||||
|
return str.replace(/^\s+|\s+$/g, ''); |
||||
|
}; |
||||
|
_ref = headerLines.reverse(); |
||||
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) { |
||||
|
line = _ref[_i]; |
||||
|
idx = line.indexOf(':'); |
||||
|
headers[trim(line.substring(0, idx))] = trim(line.substring(idx + 1)); |
||||
|
} |
||||
|
body = ''; |
||||
|
start = divider + 2; |
||||
|
if (headers['content-length']) { |
||||
|
len = parseInt(headers['content-length']); |
||||
|
body = ('' + data).substring(start, start + len); |
||||
|
} else { |
||||
|
chr = null; |
||||
|
for (i = _j = start, _ref1 = data.length; start <= _ref1 ? _j < _ref1 : _j > _ref1; i = start <= _ref1 ? ++_j : --_j) { |
||||
|
chr = data.charAt(i); |
||||
|
if (chr === Byte.NULL) { |
||||
|
break; |
||||
|
} |
||||
|
body += chr; |
||||
|
} |
||||
|
} |
||||
|
return new Frame(command, headers, body); |
||||
|
}; |
||||
|
|
||||
|
Frame.unmarshall = function(datas) { |
||||
|
var frame, frames, last_frame, r; |
||||
|
frames = datas.split(RegExp("" + Byte.NULL + Byte.LF + "*")); |
||||
|
r = { |
||||
|
frames: [], |
||||
|
partial: '' |
||||
|
}; |
||||
|
r.frames = (function() { |
||||
|
var _i, _len, _ref, _results; |
||||
|
_ref = frames.slice(0, -1); |
||||
|
_results = []; |
||||
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) { |
||||
|
frame = _ref[_i]; |
||||
|
_results.push(unmarshallSingle(frame)); |
||||
|
} |
||||
|
return _results; |
||||
|
})(); |
||||
|
last_frame = frames.slice(-1)[0]; |
||||
|
if (last_frame === Byte.LF || (last_frame.search(RegExp("" + Byte.NULL + Byte.LF + "*$"))) !== -1) { |
||||
|
r.frames.push(unmarshallSingle(last_frame)); |
||||
|
} else { |
||||
|
r.partial = last_frame; |
||||
|
} |
||||
|
return r; |
||||
|
}; |
||||
|
|
||||
|
Frame.marshall = function(command, headers, body) { |
||||
|
var frame; |
||||
|
frame = new Frame(command, headers, body); |
||||
|
return frame.toString() + Byte.NULL; |
||||
|
}; |
||||
|
|
||||
|
return Frame; |
||||
|
|
||||
|
})(); |
||||
|
|
||||
|
Client = (function() { |
||||
|
var now; |
||||
|
|
||||
|
function Client(ws) { |
||||
|
this.ws = ws; |
||||
|
this.ws.binaryType = "arraybuffer"; |
||||
|
this.counter = 0; |
||||
|
this.connected = false; |
||||
|
this.heartbeat = { |
||||
|
outgoing: 10000, |
||||
|
incoming: 10000 |
||||
|
}; |
||||
|
this.maxWebSocketFrameSize = 16 * 1024; |
||||
|
this.subscriptions = {}; |
||||
|
this.partialData = ''; |
||||
|
} |
||||
|
|
||||
|
Client.prototype.debug = function(message) { |
||||
|
var _ref; |
||||
|
return typeof window !== "undefined" && window !== null ? (_ref = window.console) != null ? _ref.log(message) : void 0 : void 0; |
||||
|
}; |
||||
|
|
||||
|
now = function() { |
||||
|
if (Date.now) { |
||||
|
return Date.now(); |
||||
|
} else { |
||||
|
return new Date().valueOf; |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
Client.prototype._transmit = function(command, headers, body) { |
||||
|
var out; |
||||
|
out = Frame.marshall(command, headers, body); |
||||
|
if (typeof this.debug === "function") { |
||||
|
this.debug(">>> " + out); |
||||
|
} |
||||
|
while (true) { |
||||
|
if (out.length > this.maxWebSocketFrameSize) { |
||||
|
this.ws.send(out.substring(0, this.maxWebSocketFrameSize)); |
||||
|
out = out.substring(this.maxWebSocketFrameSize); |
||||
|
if (typeof this.debug === "function") { |
||||
|
this.debug("remaining = " + out.length); |
||||
|
} |
||||
|
} else { |
||||
|
return this.ws.send(out); |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
Client.prototype._setupHeartbeat = function(headers) { |
||||
|
var serverIncoming, serverOutgoing, ttl, v, _ref, _ref1; |
||||
|
if ((_ref = headers.version) !== Stomp.VERSIONS.V1_1 && _ref !== Stomp.VERSIONS.V1_2) { |
||||
|
return; |
||||
|
} |
||||
|
_ref1 = (function() { |
||||
|
var _i, _len, _ref1, _results; |
||||
|
_ref1 = headers['heart-beat'].split(","); |
||||
|
_results = []; |
||||
|
for (_i = 0, _len = _ref1.length; _i < _len; _i++) { |
||||
|
v = _ref1[_i]; |
||||
|
_results.push(parseInt(v)); |
||||
|
} |
||||
|
return _results; |
||||
|
})(), serverOutgoing = _ref1[0], serverIncoming = _ref1[1]; |
||||
|
if (!(this.heartbeat.outgoing === 0 || serverIncoming === 0)) { |
||||
|
ttl = Math.max(this.heartbeat.outgoing, serverIncoming); |
||||
|
if (typeof this.debug === "function") { |
||||
|
this.debug("send PING every " + ttl + "ms"); |
||||
|
} |
||||
|
this.pinger = Stomp.setInterval(ttl, (function(_this) { |
||||
|
return function() { |
||||
|
_this.ws.send(Byte.LF); |
||||
|
return typeof _this.debug === "function" ? _this.debug(">>> PING") : void 0; |
||||
|
}; |
||||
|
})(this)); |
||||
|
} |
||||
|
if (!(this.heartbeat.incoming === 0 || serverOutgoing === 0)) { |
||||
|
ttl = Math.max(this.heartbeat.incoming, serverOutgoing); |
||||
|
if (typeof this.debug === "function") { |
||||
|
this.debug("check PONG every " + ttl + "ms"); |
||||
|
} |
||||
|
return this.ponger = Stomp.setInterval(ttl, (function(_this) { |
||||
|
return function() { |
||||
|
var delta; |
||||
|
delta = now() - _this.serverActivity; |
||||
|
if (delta > ttl * 2) { |
||||
|
if (typeof _this.debug === "function") { |
||||
|
_this.debug("did not receive server activity for the last " + delta + "ms"); |
||||
|
} |
||||
|
return _this.ws.close(); |
||||
|
} |
||||
|
}; |
||||
|
})(this)); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
Client.prototype._parseConnect = function() { |
||||
|
var args, connectCallback, errorCallback, headers; |
||||
|
args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; |
||||
|
headers = {}; |
||||
|
switch (args.length) { |
||||
|
case 2: |
||||
|
headers = args[0], connectCallback = args[1]; |
||||
|
break; |
||||
|
case 3: |
||||
|
if (args[1] instanceof Function) { |
||||
|
headers = args[0], connectCallback = args[1], errorCallback = args[2]; |
||||
|
} else { |
||||
|
headers.login = args[0], headers.passcode = args[1], connectCallback = args[2]; |
||||
|
} |
||||
|
break; |
||||
|
case 4: |
||||
|
headers.login = args[0], headers.passcode = args[1], connectCallback = args[2], errorCallback = args[3]; |
||||
|
break; |
||||
|
default: |
||||
|
headers.login = args[0], headers.passcode = args[1], connectCallback = args[2], errorCallback = args[3], headers.host = args[4]; |
||||
|
} |
||||
|
return [headers, connectCallback, errorCallback]; |
||||
|
}; |
||||
|
|
||||
|
Client.prototype.connect = function() { |
||||
|
var args, errorCallback, headers, out; |
||||
|
args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; |
||||
|
out = this._parseConnect.apply(this, args); |
||||
|
headers = out[0], this.connectCallback = out[1], errorCallback = out[2]; |
||||
|
if (typeof this.debug === "function") { |
||||
|
this.debug("Opening Web Socket..."); |
||||
|
} |
||||
|
this.ws.onmessage = (function(_this) { |
||||
|
return function(evt) { |
||||
|
var arr, c, client, data, frame, messageID, onreceive, subscription, unmarshalledData, _i, _len, _ref, _results; |
||||
|
data = typeof ArrayBuffer !== 'undefined' && evt.data instanceof ArrayBuffer ? (arr = new Uint8Array(evt.data), typeof _this.debug === "function" ? _this.debug("--- got data length: " + arr.length) : void 0, ((function() { |
||||
|
var _i, _len, _results; |
||||
|
_results = []; |
||||
|
for (_i = 0, _len = arr.length; _i < _len; _i++) { |
||||
|
c = arr[_i]; |
||||
|
_results.push(String.fromCharCode(c)); |
||||
|
} |
||||
|
return _results; |
||||
|
})()).join('')) : evt.data; |
||||
|
_this.serverActivity = now(); |
||||
|
if (data === Byte.LF) { |
||||
|
if (typeof _this.debug === "function") { |
||||
|
_this.debug("<<< PONG"); |
||||
|
} |
||||
|
return; |
||||
|
} |
||||
|
if (typeof _this.debug === "function") { |
||||
|
_this.debug("<<< " + data); |
||||
|
} |
||||
|
unmarshalledData = Frame.unmarshall(_this.partialData + data); |
||||
|
_this.partialData = unmarshalledData.partial; |
||||
|
_ref = unmarshalledData.frames; |
||||
|
_results = []; |
||||
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) { |
||||
|
frame = _ref[_i]; |
||||
|
switch (frame.command) { |
||||
|
case "CONNECTED": |
||||
|
if (typeof _this.debug === "function") { |
||||
|
_this.debug("connected to server " + frame.headers.server); |
||||
|
} |
||||
|
_this.connected = true; |
||||
|
_this._setupHeartbeat(frame.headers); |
||||
|
_results.push(typeof _this.connectCallback === "function" ? _this.connectCallback(frame) : void 0); |
||||
|
break; |
||||
|
case "MESSAGE": |
||||
|
subscription = frame.headers.subscription; |
||||
|
onreceive = _this.subscriptions[subscription] || _this.onreceive; |
||||
|
if (onreceive) { |
||||
|
client = _this; |
||||
|
messageID = frame.headers["message-id"]; |
||||
|
frame.ack = function(headers) { |
||||
|
if (headers == null) { |
||||
|
headers = {}; |
||||
|
} |
||||
|
return client.ack(messageID, subscription, headers); |
||||
|
}; |
||||
|
frame.nack = function(headers) { |
||||
|
if (headers == null) { |
||||
|
headers = {}; |
||||
|
} |
||||
|
return client.nack(messageID, subscription, headers); |
||||
|
}; |
||||
|
_results.push(onreceive(frame)); |
||||
|
} else { |
||||
|
_results.push(typeof _this.debug === "function" ? _this.debug("Unhandled received MESSAGE: " + frame) : void 0); |
||||
|
} |
||||
|
break; |
||||
|
case "RECEIPT": |
||||
|
_results.push(typeof _this.onreceipt === "function" ? _this.onreceipt(frame) : void 0); |
||||
|
break; |
||||
|
case "ERROR": |
||||
|
_results.push(typeof errorCallback === "function" ? errorCallback(frame) : void 0); |
||||
|
break; |
||||
|
default: |
||||
|
_results.push(typeof _this.debug === "function" ? _this.debug("Unhandled frame: " + frame) : void 0); |
||||
|
} |
||||
|
} |
||||
|
return _results; |
||||
|
}; |
||||
|
})(this); |
||||
|
this.ws.onclose = (function(_this) { |
||||
|
return function() { |
||||
|
var msg; |
||||
|
msg = "Whoops! Lost connection to " + _this.ws.url; |
||||
|
if (typeof _this.debug === "function") { |
||||
|
_this.debug(msg); |
||||
|
} |
||||
|
_this._cleanUp(); |
||||
|
return typeof errorCallback === "function" ? errorCallback(msg) : void 0; |
||||
|
}; |
||||
|
})(this); |
||||
|
return this.ws.onopen = (function(_this) { |
||||
|
return function() { |
||||
|
if (typeof _this.debug === "function") { |
||||
|
_this.debug('Web Socket Opened...'); |
||||
|
} |
||||
|
headers["accept-version"] = Stomp.VERSIONS.supportedVersions(); |
||||
|
headers["heart-beat"] = [_this.heartbeat.outgoing, _this.heartbeat.incoming].join(','); |
||||
|
return _this._transmit("CONNECT", headers); |
||||
|
}; |
||||
|
})(this); |
||||
|
}; |
||||
|
|
||||
|
Client.prototype.disconnect = function(disconnectCallback, headers) { |
||||
|
if (headers == null) { |
||||
|
headers = {}; |
||||
|
} |
||||
|
this._transmit("DISCONNECT", headers); |
||||
|
this.ws.onclose = null; |
||||
|
this.ws.close(); |
||||
|
this._cleanUp(); |
||||
|
return typeof disconnectCallback === "function" ? disconnectCallback() : void 0; |
||||
|
}; |
||||
|
|
||||
|
Client.prototype._cleanUp = function() { |
||||
|
this.connected = false; |
||||
|
if (this.pinger) { |
||||
|
Stomp.clearInterval(this.pinger); |
||||
|
} |
||||
|
if (this.ponger) { |
||||
|
return Stomp.clearInterval(this.ponger); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
Client.prototype.send = function(destination, headers, body) { |
||||
|
if (headers == null) { |
||||
|
headers = {}; |
||||
|
} |
||||
|
if (body == null) { |
||||
|
body = ''; |
||||
|
} |
||||
|
headers.destination = destination; |
||||
|
return this._transmit("SEND", headers, body); |
||||
|
}; |
||||
|
|
||||
|
Client.prototype.subscribe = function(destination, callback, headers) { |
||||
|
var client; |
||||
|
if (headers == null) { |
||||
|
headers = {}; |
||||
|
} |
||||
|
if (!headers.id) { |
||||
|
headers.id = "sub-" + this.counter++; |
||||
|
} |
||||
|
headers.destination = destination; |
||||
|
this.subscriptions[headers.id] = callback; |
||||
|
this._transmit("SUBSCRIBE", headers); |
||||
|
client = this; |
||||
|
return { |
||||
|
id: headers.id, |
||||
|
unsubscribe: function() { |
||||
|
return client.unsubscribe(headers.id); |
||||
|
} |
||||
|
}; |
||||
|
}; |
||||
|
|
||||
|
Client.prototype.unsubscribe = function(id) { |
||||
|
delete this.subscriptions[id]; |
||||
|
return this._transmit("UNSUBSCRIBE", { |
||||
|
id: id |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
Client.prototype.begin = function(transaction) { |
||||
|
var client, txid; |
||||
|
txid = transaction || "tx-" + this.counter++; |
||||
|
this._transmit("BEGIN", { |
||||
|
transaction: txid |
||||
|
}); |
||||
|
client = this; |
||||
|
return { |
||||
|
id: txid, |
||||
|
commit: function() { |
||||
|
return client.commit(txid); |
||||
|
}, |
||||
|
abort: function() { |
||||
|
return client.abort(txid); |
||||
|
} |
||||
|
}; |
||||
|
}; |
||||
|
|
||||
|
Client.prototype.commit = function(transaction) { |
||||
|
return this._transmit("COMMIT", { |
||||
|
transaction: transaction |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
Client.prototype.abort = function(transaction) { |
||||
|
return this._transmit("ABORT", { |
||||
|
transaction: transaction |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
Client.prototype.ack = function(messageID, subscription, headers) { |
||||
|
if (headers == null) { |
||||
|
headers = {}; |
||||
|
} |
||||
|
headers["message-id"] = messageID; |
||||
|
headers.subscription = subscription; |
||||
|
return this._transmit("ACK", headers); |
||||
|
}; |
||||
|
|
||||
|
Client.prototype.nack = function(messageID, subscription, headers) { |
||||
|
if (headers == null) { |
||||
|
headers = {}; |
||||
|
} |
||||
|
headers["message-id"] = messageID; |
||||
|
headers.subscription = subscription; |
||||
|
return this._transmit("NACK", headers); |
||||
|
}; |
||||
|
|
||||
|
return Client; |
||||
|
|
||||
|
})(); |
||||
|
|
||||
|
Stomp = { |
||||
|
VERSIONS: { |
||||
|
V1_0: '1.0', |
||||
|
V1_1: '1.1', |
||||
|
V1_2: '1.2', |
||||
|
supportedVersions: function() { |
||||
|
return '1.1,1.0'; |
||||
|
} |
||||
|
}, |
||||
|
client: function(url, protocols) { |
||||
|
var klass, ws; |
||||
|
if (protocols == null) { |
||||
|
protocols = ['v10.stomp', 'v11.stomp']; |
||||
|
} |
||||
|
klass = Stomp.WebSocketClass || WebSocket; |
||||
|
ws = new klass(url, protocols); |
||||
|
return new Client(ws); |
||||
|
}, |
||||
|
over: function(ws) { |
||||
|
return new Client(ws); |
||||
|
}, |
||||
|
Frame: Frame |
||||
|
}; |
||||
|
|
||||
|
if (typeof exports !== "undefined" && exports !== null) { |
||||
|
exports.Stomp = Stomp; |
||||
|
} |
||||
|
|
||||
|
if (typeof window !== "undefined" && window !== null) { |
||||
|
Stomp.setInterval = function(interval, f) { |
||||
|
return window.setInterval(f, interval); |
||||
|
}; |
||||
|
Stomp.clearInterval = function(id) { |
||||
|
return window.clearInterval(id); |
||||
|
}; |
||||
|
window.Stomp = Stomp; |
||||
|
} else if (!exports) { |
||||
|
self.Stomp = Stomp; |
||||
|
} |
||||
|
|
||||
|
}).call(this); |
||||
@ -0,0 +1,28 @@ |
|||||
|
body,div,p,h1,h2,h3,h4,h5,h6,ul,li,dl,dt,a,input,button,textarea,select{ |
||||
|
margin: 0; |
||||
|
padding: 0; |
||||
|
outline: none; |
||||
|
} |
||||
|
html,body{ |
||||
|
font-family:Helvetica Neue,Helvetica,Arial,Microsoft Yahei,Hiragino Sans GB,Heiti SC,WenQuanYi Micro Hei,sans-serif; |
||||
|
color: #333333; |
||||
|
background-color: #ffffff; |
||||
|
font-size: .4rem; |
||||
|
} |
||||
|
a{ |
||||
|
text-decoration: none; |
||||
|
} |
||||
|
ul,li{ |
||||
|
list-style: none; |
||||
|
} |
||||
|
input{ |
||||
|
font: normal; |
||||
|
} |
||||
|
input:focus,a:focus{ |
||||
|
outline: none; |
||||
|
} |
||||
|
|
||||
|
html, |
||||
|
body { |
||||
|
height: 100%; |
||||
|
} |
||||
@ -0,0 +1,35 @@ |
|||||
|
// 获取年月日等日期时间
|
||||
|
function getDate() { |
||||
|
let myDate = new Date(); |
||||
|
let month = myDate.getMonth() + 1; |
||||
|
let day = myDate.getDate(); |
||||
|
return {myDate, month, day} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
//通过身份证号计算年龄、性别、出生日期
|
||||
|
export const idCard = (userCard, num) => { |
||||
|
let birth |
||||
|
//获取出生日期
|
||||
|
if (num == 1) { |
||||
|
birth = userCard.substring(6, 10) + "-" + userCard.substring(10, 12) + "-" + userCard.substring(12, 14); |
||||
|
return birth; |
||||
|
} |
||||
|
//获取性别
|
||||
|
if (num == 2) { |
||||
|
if (parseInt(userCard.substr(16, 1)) % 2 == 1) { |
||||
|
return "男"; |
||||
|
} else { |
||||
|
return "女"; |
||||
|
} |
||||
|
} |
||||
|
//获取年龄
|
||||
|
if (num == 3) { |
||||
|
let {myDate, month, day} = getDate() |
||||
|
let age = myDate.getFullYear() - userCard.substring(6, 10) - 1; |
||||
|
if (userCard.substring(10, 12) < month || userCard.substring(10, 12) == month && userCard.substring(12, 14) <= day) { |
||||
|
age++; |
||||
|
} |
||||
|
return age; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,57 @@ |
|||||
|
<template> |
||||
|
<div class="hello"> |
||||
|
<h1>{{ msg }}</h1> |
||||
|
<p> |
||||
|
For a guide and recipes on how to configure / customize this project,<br> |
||||
|
check out the |
||||
|
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>. |
||||
|
</p> |
||||
|
<h3>Installed CLI Plugins</h3> |
||||
|
<ul> |
||||
|
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li> |
||||
|
</ul> |
||||
|
<h3>Essential Links</h3> |
||||
|
<ul> |
||||
|
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li> |
||||
|
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li> |
||||
|
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li> |
||||
|
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li> |
||||
|
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li> |
||||
|
</ul> |
||||
|
<h3>Ecosystem</h3> |
||||
|
<ul> |
||||
|
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li> |
||||
|
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li> |
||||
|
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li> |
||||
|
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li> |
||||
|
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li> |
||||
|
</ul> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
name: 'HelloWorld', |
||||
|
props: { |
||||
|
msg: String |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<!-- Add "scoped" attribute to limit CSS to this component only --> |
||||
|
<style scoped lang="scss"> |
||||
|
h3 { |
||||
|
margin: 40px 0 0; |
||||
|
} |
||||
|
ul { |
||||
|
list-style-type: none; |
||||
|
padding: 0; |
||||
|
} |
||||
|
li { |
||||
|
display: inline-block; |
||||
|
margin: 0 10px; |
||||
|
} |
||||
|
a { |
||||
|
color: #42b983; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,125 @@ |
|||||
|
<template> |
||||
|
<div class="pop" v-show="showModal"> |
||||
|
<div class="pop-mian"> |
||||
|
<div class="pop-tit">{{title}}</div> |
||||
|
<div class="pop-con1"> |
||||
|
<h3>{{subTitle}}</h3> |
||||
|
<p>{{message}}</p> |
||||
|
<p v-if="message1!==''">{{message1}}</p> |
||||
|
<p v-if="message2!==''">{{message2}}</p> |
||||
|
</div> |
||||
|
<div class="pop-btn"> |
||||
|
<div class="btn-color" v-if="btnType==1" @click="$emit('cancel')">{{sureText}}</div> |
||||
|
<div class="btn-color" v-if="btnType==2" @click="$emit('submit')">{{sureText}}</div> |
||||
|
</div> |
||||
|
<div class="pop-close" @click="$emit('cancel')"></div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script> |
||||
|
export default { |
||||
|
data() { |
||||
|
return {}; |
||||
|
}, |
||||
|
mounted(){ |
||||
|
|
||||
|
}, |
||||
|
props: { |
||||
|
showModal: Boolean, |
||||
|
sureText: { |
||||
|
type: String, |
||||
|
default: "我知道了" |
||||
|
}, |
||||
|
title:String, |
||||
|
subTitle:String, |
||||
|
message:String, |
||||
|
btnType:String, |
||||
|
message1:String, |
||||
|
message2:String |
||||
|
}, |
||||
|
}; |
||||
|
</script> |
||||
|
<style lang="scss" scoped> |
||||
|
.pop { |
||||
|
z-index: 999; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
position: fixed; |
||||
|
top: 0; |
||||
|
left: 0; |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
background-color: rgba(0, 0, 0, 0.7); |
||||
|
.pop-mian { |
||||
|
width: 5.7rem; |
||||
|
background: #ce0404; |
||||
|
border-radius: 0.4rem; |
||||
|
padding: 0.3rem 0.2rem; |
||||
|
box-sizing: border-box; |
||||
|
text-align: center; |
||||
|
margin: 0 auto; |
||||
|
position: relative; |
||||
|
.pop-close { |
||||
|
width: 0.3rem; |
||||
|
height: 0.3rem; |
||||
|
background: url("https://v.ringbox.cn/douyin/img/close.png") no-repeat |
||||
|
center; |
||||
|
background-size: 100% 100%; |
||||
|
position: absolute; |
||||
|
top: 0.2rem; |
||||
|
right: 0.2rem; |
||||
|
} |
||||
|
.pop-btn { |
||||
|
height: 0.8rem; |
||||
|
.btn-color { |
||||
|
width: 4.4rem; |
||||
|
height: 0.8rem; |
||||
|
font-size: 0.3rem; |
||||
|
color: #ffffff; |
||||
|
line-height: 0.8rem; |
||||
|
background: linear-gradient( |
||||
|
0deg, |
||||
|
#dba81a 0%, |
||||
|
#ffc107 100% |
||||
|
); |
||||
|
border-radius: 0.4rem; |
||||
|
margin: 0 auto; |
||||
|
margin-bottom: 0.3rem; |
||||
|
} |
||||
|
} |
||||
|
.pop-tit { |
||||
|
position: relative; |
||||
|
height: 0.4rem; |
||||
|
line-height: 0.4rem; |
||||
|
font-size: 0.33rem; |
||||
|
color: #fafafa; |
||||
|
font-weight: 600; |
||||
|
} |
||||
|
.pop-con { |
||||
|
padding-top: 2.41rem; |
||||
|
background: url("https://vediocnd.corpring.com/%E5%8F%8C%E5%8D%81%E4%BA%8C%E9%87%91%E5%B8%81%E7%BA%A2%E5%8C%85%E8%B4%AD%E7%89%A9%E8%A3%85%E9%A5%B0%E7%9F%A2%E9%87%8F.png") |
||||
|
no-repeat center 0.2rem; |
||||
|
background-size: 2.5rem 2rem; |
||||
|
font-size: 0.26rem; |
||||
|
color: #fff; |
||||
|
line-height: 1.5; |
||||
|
text-align: center; |
||||
|
padding-bottom: 0.3rem; |
||||
|
h3 { |
||||
|
line-height: 2.5; |
||||
|
} |
||||
|
} |
||||
|
.pop-con1 { |
||||
|
font-size: 0.26rem; |
||||
|
color: #fff; |
||||
|
line-height: 1.5; |
||||
|
text-align: center; |
||||
|
padding-bottom: 0.3rem; |
||||
|
margin-top: 0.2rem; |
||||
|
h3 { |
||||
|
line-height: 2.5; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,95 @@ |
|||||
|
<template> |
||||
|
<div class="dialog-box"> |
||||
|
<div class="dialog-bgi"> |
||||
|
<div class="input-box1"> |
||||
|
<div class="btn1">تەستىق نۇمۇرغا ئىرىشىش</div> |
||||
|
<input type="text" placeholder="تەستىق نۇمۇرىنى كىرگۈزۈڭ"> |
||||
|
</div> |
||||
|
<div class="transact"></div> |
||||
|
<div class="toolTips"> |
||||
|
<span>此页面可持续数秒,请耐心等待切勿刷新或关闭</span> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="dialog-close" @click="closeVan"></div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
name: "dialog" |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
.dialog-box{ |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
background-color: rgba(0, 0, 0, 0.8); |
||||
|
padding-top: 2rem; |
||||
|
box-sizing: border-box; |
||||
|
position: fixed; |
||||
|
top: 0; |
||||
|
z-index: 100; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
align-items: center; |
||||
|
//justify-content: center; |
||||
|
.dialog-bgi{ |
||||
|
width: 80%; |
||||
|
height: 7rem; |
||||
|
position: relative; |
||||
|
background: url("https://vediocnd.corpring.com/dialog-bgi.png") no-repeat center; |
||||
|
background-size: 100% 100%; |
||||
|
|
||||
|
.input-box1{ |
||||
|
width: 83%; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
position: absolute; |
||||
|
top: 2.765rem; |
||||
|
left: .51rem; |
||||
|
//background-color: yellow; |
||||
|
|
||||
|
.btn1{ |
||||
|
width: 33%; |
||||
|
font-size: .05rem; |
||||
|
//background-color: green; |
||||
|
} |
||||
|
input{ |
||||
|
width: 67%; |
||||
|
height: .8rem; |
||||
|
border-radius: 0 .2rem .2rem 0; |
||||
|
border: none; |
||||
|
text-align: right; |
||||
|
padding-right: .2rem; |
||||
|
//background-color: red; |
||||
|
} |
||||
|
} |
||||
|
.transact{ |
||||
|
width: 70%; |
||||
|
height: 1rem; |
||||
|
position: absolute; |
||||
|
top: 4.18rem; |
||||
|
left: 15%; |
||||
|
background: url("https://vediocnd.corpring.com/transact-btn.png") no-repeat center; |
||||
|
background-size: 100% 100%; |
||||
|
} |
||||
|
|
||||
|
.toolTips{ |
||||
|
position: absolute; |
||||
|
top: 6rem; |
||||
|
left: .28rem; |
||||
|
font-size: .26rem; |
||||
|
color: #fff; |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
.dialog-close{ |
||||
|
width: 0.7rem; |
||||
|
height: 0.7rem; |
||||
|
margin-top: 2rem; |
||||
|
background: url("../../assets/close.png") no-repeat center; |
||||
|
background-size: 100% 100%; |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,209 @@ |
|||||
|
<template> |
||||
|
<div v-if="showModal" class="modal-contents"> |
||||
|
<div :style="{background: `url(${backgroundImg}) no-repeat #fff`,backgroundSize: '100% 50%'}" class="content-box"> |
||||
|
<div class="close-icon" @click="cancel"></div> |
||||
|
<div class="input-box"> |
||||
|
<input |
||||
|
v-model="phoneCode" |
||||
|
:maxlength="codeLength" |
||||
|
onKeypress="javascript:if(event.keyCode == 32)event.returnValue =false;" |
||||
|
placeholder="请输入验证码" |
||||
|
v-on:input="inputCode" |
||||
|
/> |
||||
|
<div class="count-box"> |
||||
|
<a v-if="ifCodeAgain" class="btn-get_code" @click="newCode" |
||||
|
>获取验证码</a |
||||
|
> |
||||
|
<a v-else class="btn-get_code">已发送({{ counter }}S)</a> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="footer"> |
||||
|
<div class="order-btn" @click="ToCollect"> |
||||
|
立即办理 |
||||
|
</div> |
||||
|
<b class="reminder">请耐心等待验证码,切勿刷新或关闭</b |
||||
|
> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
components: {}, |
||||
|
props: { |
||||
|
showModal: { |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
}, |
||||
|
codeLength: { |
||||
|
type: Number, |
||||
|
default: 4 |
||||
|
}, |
||||
|
count: { |
||||
|
type: Number, |
||||
|
default: 60 |
||||
|
}, |
||||
|
backgroundImg: { |
||||
|
type: String, |
||||
|
default: 'https://vediocnd.corpring.com/xxlTwoWindowSc3g5g.png' |
||||
|
}, |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
ifCodeAgain: true, // 显示文字还是倒计时 |
||||
|
counter: null, // 倒计时时间 |
||||
|
phoneCode: null, // 验证码 |
||||
|
timer: null, // 定时器 |
||||
|
}; |
||||
|
}, |
||||
|
watch: { |
||||
|
// 父组件传过来的时间 |
||||
|
count: { |
||||
|
handler(newVal, oldVal) { |
||||
|
this.counter = newVal |
||||
|
}, |
||||
|
immediate: true |
||||
|
}, |
||||
|
}, |
||||
|
computed: {}, |
||||
|
methods: { |
||||
|
// input框输入事件 |
||||
|
inputCode() { |
||||
|
if (this.codeLength == this.phoneCode.length) { |
||||
|
this.$emit('inputCode', this.phoneCode,'MODAL') |
||||
|
this.cancel() |
||||
|
} |
||||
|
}, |
||||
|
// 获取验证码 |
||||
|
newCode() { |
||||
|
if (this.ifCodeAgain) { |
||||
|
this.ifCodeAgain = false |
||||
|
this.counterDown() |
||||
|
this.$emit('newCode') |
||||
|
} |
||||
|
}, |
||||
|
// 关闭弹窗 |
||||
|
cancel() { |
||||
|
Object.assign(this.$data, this.$options.data()) |
||||
|
this.$emit('cancel') |
||||
|
}, |
||||
|
// 立即办理 |
||||
|
ToCollect() { |
||||
|
this.$emit('ToCollect') |
||||
|
this.cancel() |
||||
|
}, |
||||
|
// 倒计时 |
||||
|
counterDown() { |
||||
|
if (!this.ifCodeAgain) { |
||||
|
this.timer = setInterval(() => { |
||||
|
if (this.counter <= 0) { |
||||
|
clearInterval(this.timer) |
||||
|
this.ifCodeAgain = true |
||||
|
this.counter = this.count |
||||
|
return |
||||
|
} |
||||
|
this.counter-- |
||||
|
}, 1000) |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
created() { |
||||
|
}, |
||||
|
mounted() { |
||||
|
}, |
||||
|
}; |
||||
|
</script> |
||||
|
<style lang="scss" scoped> |
||||
|
.modal-contents { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
background-color: rgba(0, 0, 0, 0.8); |
||||
|
position: fixed; |
||||
|
top: 0; |
||||
|
z-index: 150; |
||||
|
|
||||
|
.content-box { |
||||
|
width: 75%; |
||||
|
height: 6.6rem; |
||||
|
border-radius: .15rem .45rem .2rem .2rem; |
||||
|
position: relative; |
||||
|
padding-top: 3.5rem; |
||||
|
box-sizing: border-box; |
||||
|
|
||||
|
.close-icon { |
||||
|
width: .5rem; |
||||
|
height: .5rem; |
||||
|
background: url("https://vediocnd.corpring.com/wClose.png") no-repeat; |
||||
|
background-size: 100% 100%; |
||||
|
position: absolute; |
||||
|
top: .08rem; |
||||
|
right: .08rem; |
||||
|
} |
||||
|
|
||||
|
.input-box { |
||||
|
width: 85%; |
||||
|
margin: 0 auto; |
||||
|
display: flex; |
||||
|
background-color: rgb(100, 86, 252); |
||||
|
border-radius: .25rem; |
||||
|
position: relative; |
||||
|
|
||||
|
input { |
||||
|
width: 100%; |
||||
|
height: 1rem; |
||||
|
border-radius: .25rem; |
||||
|
border: none; |
||||
|
padding-left: .5rem; |
||||
|
box-sizing: border-box; |
||||
|
background-color: rgb(100, 86, 252); |
||||
|
|
||||
|
&::placeholder { |
||||
|
color: #fff; |
||||
|
font-size: .3rem; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.count-box { |
||||
|
color: #fff; |
||||
|
line-height: 1rem; |
||||
|
font-size: .3rem; |
||||
|
position: absolute; |
||||
|
right: .1rem; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.footer { |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
align-items: center; |
||||
|
|
||||
|
.order-btn { |
||||
|
margin-top: .5rem; |
||||
|
background-color: rgb(76, 105, 252); |
||||
|
width: 65%; |
||||
|
height: .6rem; |
||||
|
border-radius: .5rem; |
||||
|
color: #fff; |
||||
|
text-align: center; |
||||
|
font-size: .38rem; |
||||
|
line-height: .6rem; |
||||
|
font-weight: bold; |
||||
|
//background: url("https://vediocnd.corpring.com/threePayClick.png"); |
||||
|
} |
||||
|
|
||||
|
.reminder { |
||||
|
margin-top: .4rem; |
||||
|
color: rgb(0, 0, 0); |
||||
|
font-size: 0.23rem; |
||||
|
font-weight: normal; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,95 @@ |
|||||
|
<template> |
||||
|
<div class="navbar-list"> |
||||
|
<ul class="flex-imd"> |
||||
|
<li v-for="(item,index) in list" |
||||
|
:key="index" |
||||
|
class="navbar-item" |
||||
|
:class="activeIndex===index?'act':''" |
||||
|
@click="chooseNav(item,index)" |
||||
|
:data-navid='item.name' |
||||
|
> |
||||
|
{{item.name}} |
||||
|
</li> |
||||
|
</ul> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
props:{ |
||||
|
list:{ |
||||
|
type:Array, |
||||
|
default(){ |
||||
|
return [] |
||||
|
} |
||||
|
}, |
||||
|
activeIndex:{ |
||||
|
type:Number, |
||||
|
default:0, |
||||
|
} |
||||
|
}, |
||||
|
data () { |
||||
|
return { |
||||
|
// activeIndex:0, |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
chooseNav (item,index) { |
||||
|
// console.log(e.target.dataset.navid) |
||||
|
// this.currNavbar = Number(item.name) |
||||
|
// this.activeIndex = index; |
||||
|
this.$emit('tab',{ |
||||
|
data:item, |
||||
|
index:index |
||||
|
}) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style> |
||||
|
.navbar-list{ |
||||
|
width: 100%; |
||||
|
height: 0.6rem; |
||||
|
position: relative; |
||||
|
overflow-x: scroll; |
||||
|
overflow-y: hidden; |
||||
|
background: #8020fe; |
||||
|
color: #fff; |
||||
|
font-size: 0.34rem; |
||||
|
border-radius: 0.1rem; |
||||
|
margin-bottom: 0.3rem; |
||||
|
padding: 0.08rem 0; |
||||
|
} |
||||
|
.navbar-list>ul{ |
||||
|
/* padding: 0 20px; */ |
||||
|
position: absolute; |
||||
|
height: 0.6rem; |
||||
|
left: 0; |
||||
|
display: flex; |
||||
|
flex-flow: row nowrap; |
||||
|
} |
||||
|
.navbar-item{ |
||||
|
/* width: 120px; */ |
||||
|
width: 1.6rem; |
||||
|
padding: 0px 18px; |
||||
|
box-sizing: border-box; |
||||
|
height: 0.6rem; |
||||
|
display: flex; |
||||
|
flex-flow: column nowrap; |
||||
|
justify-content: space-around; |
||||
|
align-items: center; |
||||
|
cursor: pointer; |
||||
|
/* margin-right: 10px; */ |
||||
|
} |
||||
|
.navbar-list::-webkit-scrollbar { |
||||
|
display: none; |
||||
|
} |
||||
|
.navbar-item.act{ |
||||
|
/* background-image: -webkit-linear-gradient(left, #ff512f, #dd2476); |
||||
|
-webkit-background-clip: text; |
||||
|
-webkit-text-fill-color: transparent; */ |
||||
|
font-weight: bold; |
||||
|
color: #fe3d54; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,69 @@ |
|||||
|
import Vue from 'vue' |
||||
|
import App from './App.vue' |
||||
|
import router from './router' |
||||
|
import Api from './api/index' |
||||
|
import VueAxios from 'vue-axios' |
||||
|
import axios from 'axios' |
||||
|
import VueCookie from 'vue-cookie' |
||||
|
import VueLazyload from 'vue-lazyload' |
||||
|
import Mint from 'mint-ui'; |
||||
|
import md5 from 'js-md5' |
||||
|
import 'mint-ui/lib/style.css'; |
||||
|
import scroll from 'vue-seamless-scroll' |
||||
|
import VueAwesomeSwiper from 'vue-awesome-swiper' |
||||
|
import '../node_modules/swiper/swiper-bundle.css' |
||||
|
import VueLuckyCanvas from '@lucky-canvas/vue' |
||||
|
import SlideVerify from 'vue-monoplasty-slide-verify'; |
||||
|
Vue.use(SlideVerify); |
||||
|
Vue.use(VueLuckyCanvas) |
||||
|
Vue.use(VueAwesomeSwiper) |
||||
|
Vue.use(VueAxios, axios); |
||||
|
Vue.use(Api); |
||||
|
Vue.use(VueCookie) |
||||
|
Vue.use(VueLazyload) |
||||
|
Vue.use(Mint); |
||||
|
Vue.use(scroll) |
||||
|
Vue.prototype.$md5 = md5; |
||||
|
|
||||
|
Vue.config.productionTip = false |
||||
|
|
||||
|
// Vue.use(VueLazyload, {
|
||||
|
// loading: 'dist/loading.gif',
|
||||
|
// })
|
||||
|
|
||||
|
//引入外部js文件
|
||||
|
Vue.component('remote-script', { |
||||
|
render: function (createElement) { |
||||
|
var self = this; |
||||
|
return createElement('script', { |
||||
|
attrs: { |
||||
|
type: 'text/javascript', |
||||
|
src: this.src |
||||
|
}, |
||||
|
on: { |
||||
|
load: function (event) { |
||||
|
self.$emit('load', event); |
||||
|
}, |
||||
|
error: function (event) { |
||||
|
self.$emit('error', event); |
||||
|
}, |
||||
|
readystatechange: function (event) { |
||||
|
if (this.readyState == 'complete') { |
||||
|
self.$emit('load', event); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
}, |
||||
|
props: { |
||||
|
src: { |
||||
|
type: String, |
||||
|
required: true |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
new Vue({ |
||||
|
router, |
||||
|
render: h => h(App) |
||||
|
}).$mount('#app') |
||||
@ -0,0 +1,37 @@ |
|||||
|
import Vue from 'vue' |
||||
|
import VueRouter from 'vue-router' |
||||
|
|
||||
|
Vue.use(VueRouter) |
||||
|
|
||||
|
const routes = [ |
||||
|
|
||||
|
|
||||
|
{ |
||||
|
path: '/vip', |
||||
|
name: 'vip', |
||||
|
component: () => import('../views/hotVIPPages/vip.vue') |
||||
|
}, |
||||
|
{ |
||||
|
path: '/recieveVIP', |
||||
|
name: 'recieveVIP', |
||||
|
component: () => import('../views/hotVIPPages/recieveVIP.vue') |
||||
|
}, |
||||
|
{ |
||||
|
path: '/hotVIPpayback', |
||||
|
name: 'hotVIPpayback', |
||||
|
component: () => import('../views/hotVIPPages/hotVIPpayback.vue') |
||||
|
}, |
||||
|
|
||||
|
{ |
||||
|
path: '/privacy', |
||||
|
name: 'privacy', |
||||
|
component: () => import('../views/hotVIPPages/privacy.vue') |
||||
|
}, |
||||
|
|
||||
|
] |
||||
|
|
||||
|
const router = new VueRouter({ |
||||
|
routes |
||||
|
}) |
||||
|
|
||||
|
export default router |
||||
@ -0,0 +1,88 @@ |
|||||
|
|
||||
|
|
||||
|
//身份证校验函数
|
||||
|
function IdCardValidate(idCard) { |
||||
|
idCard = idCard.replace(/\s+/g, ""); //去掉字符串头尾空格
|
||||
|
if (idCard.length == 15) { |
||||
|
return isValidityBrithBy15IdCard(idCard); //进行15位身份证的验证
|
||||
|
} else if (idCard.length == 18) { |
||||
|
var a_idCard = idCard.split(""); // 得到身份证数组
|
||||
|
if (isValidityBrithBy18IdCard(idCard) && isTrueValidateCodeBy18IdCard(a_idCard)) { //进行18位身份证的基本验证和第18位的验证
|
||||
|
return true; |
||||
|
} else { |
||||
|
return false; |
||||
|
} |
||||
|
} else { |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 判断身份证号码为18位时最后的验证位是否正确 |
||||
|
* @param a_idCard 身份证号码数组 |
||||
|
* @return |
||||
|
*/ |
||||
|
function isTrueValidateCodeBy18IdCard(a_idCard) { |
||||
|
var Wi = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1]; // 加权因子
|
||||
|
var ValideCode = [1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2]; // 身份证验证位值.10代表X
|
||||
|
|
||||
|
var sum = 0; // 声明加权求和变量
|
||||
|
if (a_idCard[17].toLowerCase() == 'x') { |
||||
|
a_idCard[17] = 10; // 将最后位为x的验证码替换为10方便后续操作
|
||||
|
} |
||||
|
for (var i = 0; i < 17; i++) { |
||||
|
sum += Wi[i] * a_idCard[i]; // 加权求和
|
||||
|
} |
||||
|
valCodePosition = sum % 11; // 得到验证码所位置
|
||||
|
if (a_idCard[17] == ValideCode[valCodePosition]) { |
||||
|
return true; |
||||
|
} else { |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 验证18位数身份证号码中的生日是否是有效生日 |
||||
|
* @param idCard 18位书身份证字符串 |
||||
|
* @return |
||||
|
*/ |
||||
|
function isValidityBrithBy18IdCard(idCard18) { |
||||
|
var year = idCard18.substring(6, 10); |
||||
|
var month = idCard18.substring(10, 12); |
||||
|
var day = idCard18.substring(12, 14); |
||||
|
var temp_date = new Date(year, parseFloat(month) - 1, parseFloat(day)); |
||||
|
// 这里用getFullYear()获取年份,避免千年虫问题
|
||||
|
if (temp_date.getFullYear() != parseFloat(year) |
||||
|
|| temp_date.getMonth() != parseFloat(month) - 1 |
||||
|
|| temp_date.getDate() != parseFloat(day)) { |
||||
|
return false; |
||||
|
} else { |
||||
|
return true; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 验证15位数身份证号码中的生日是否是有效生日 |
||||
|
* @param idCard15 15位书身份证字符串 |
||||
|
* @return |
||||
|
*/ |
||||
|
function isValidityBrithBy15IdCard(idCard15) { |
||||
|
var year = idCard15.substring(6, 8); |
||||
|
var month = idCard15.substring(8, 10); |
||||
|
var day = idCard15.substring(10, 12); |
||||
|
var temp_date = new Date(year, parseFloat(month) - 1, parseFloat(day)); |
||||
|
// 对于老身份证中的你年龄则不需考虑千年虫问题而使用getYear()方法
|
||||
|
if (temp_date.getYear() != parseFloat(year) |
||||
|
|| temp_date.getMonth() != parseFloat(month) - 1 |
||||
|
|| temp_date.getDate() != parseFloat(day)) { |
||||
|
return false; |
||||
|
} else { |
||||
|
return true; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
module.exports = { |
||||
|
IdCardValidate |
||||
|
} |
||||
|
|
||||
@ -0,0 +1,50 @@ |
|||||
|
/** |
||||
|
* @desc 函数节流 |
||||
|
* @param fn 函数 |
||||
|
* @param gapTime 延迟执行毫秒数 |
||||
|
*/ |
||||
|
export function throttle (fn, gapTime) { |
||||
|
if (gapTime === null || gapTime === undefined) { |
||||
|
gapTime = 1500 |
||||
|
} |
||||
|
|
||||
|
let _lastTime = null |
||||
|
|
||||
|
// 返回新的函数
|
||||
|
return function () { |
||||
|
let _nowTime = +new Date() |
||||
|
if (_nowTime - _lastTime > gapTime || !_lastTime) { |
||||
|
fn.apply(this, arguments) // 将this和参数传给原函数
|
||||
|
_lastTime = _nowTime |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* @desc 函数防抖 |
||||
|
* @param func 函数 |
||||
|
* @param wait 延迟执行毫秒数 |
||||
|
* @param immediate true 表立即执行,false 表非立即执行 |
||||
|
*/ |
||||
|
export function debounce (func, wait, immediate) { |
||||
|
let timeout |
||||
|
|
||||
|
return function () { |
||||
|
let context = this |
||||
|
let args = arguments |
||||
|
|
||||
|
if (timeout) clearTimeout(timeout) |
||||
|
if (immediate) { |
||||
|
var callNow = !timeout |
||||
|
timeout = setTimeout(() => { |
||||
|
timeout = null |
||||
|
}, wait) |
||||
|
if (callNow) func.apply(context, args) |
||||
|
} else { |
||||
|
timeout = setTimeout(function () { |
||||
|
func.apply(context, args) |
||||
|
}, wait) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,204 @@ |
|||||
|
<template> |
||||
|
<div class="hotVip-payback-wrap"> |
||||
|
<!-- 头图 --> |
||||
|
<div class="top-img"></div> |
||||
|
|
||||
|
|
||||
|
|
||||
|
<div class="right-box"> |
||||
|
<div class="title">会员领取方式</div> |
||||
|
<div class="tips">微信搜索 “次元意境” 公众号<br/>点击【会员福利 - 会员月月领】进行兑换</div> |
||||
|
<img class="icon" src="https://img.bnyer.cn/vip/%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20230804183929.jpg" alt=""> |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
|
||||
|
|
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
|
||||
|
export default { |
||||
|
data() { |
||||
|
return{ |
||||
|
mobile: '', |
||||
|
} |
||||
|
}, |
||||
|
created(){ |
||||
|
document.documentElement.scrollTop = 0; |
||||
|
document.title = "开通成功"; |
||||
|
}, |
||||
|
|
||||
|
mounted() { |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
methods: { |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
|
||||
|
.hotVip-payback-wrap { |
||||
|
width: 100%; |
||||
|
min-height: 100%; |
||||
|
height: auto; |
||||
|
|
||||
|
position: absolute; |
||||
|
background-color: #e53c51; |
||||
|
// padding: 2rem; |
||||
|
// box-sizing: border-box; |
||||
|
padding-bottom: 1rem; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
align-items: center; |
||||
|
// justify-content: center; |
||||
|
overflow-x: hidden; |
||||
|
overflow-y: scroll; |
||||
|
|
||||
|
.top-img { |
||||
|
background-image: url('https://img.bnyer.cn/vip/pay-top-img.png'); |
||||
|
background-size: 100% 100%; |
||||
|
width: 100%; |
||||
|
// height: 360px; |
||||
|
height: 6.8rem; |
||||
|
margin-bottom: -0.7em; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
.right-box { |
||||
|
width: 87%; |
||||
|
left: 0rem; |
||||
|
right: 0rem; |
||||
|
position: relative; |
||||
|
margin-top: 0.5rem; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
align-items: center; |
||||
|
background-color: #fff; |
||||
|
|
||||
|
box-sizing: border-box; |
||||
|
padding:20px 0px; |
||||
|
border-radius: 10px; |
||||
|
text-align: center; |
||||
|
|
||||
|
.icon { |
||||
|
margin-top: 15px; |
||||
|
width: 4rem; |
||||
|
height: 4rem; |
||||
|
// background-color: #c63243; |
||||
|
} |
||||
|
.title { |
||||
|
color: #c63243; |
||||
|
font-size: 0.3rem; |
||||
|
font-weight: 600; |
||||
|
} |
||||
|
|
||||
|
.right-item-box { |
||||
|
width: 100%; |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
margin-top: 15px; |
||||
|
box-sizing: border-box; |
||||
|
padding: 0px 5px; |
||||
|
.right-item { |
||||
|
width: 50%; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
align-items: center; |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
.sub-title { |
||||
|
font-size: 0.28rem; |
||||
|
font-weight: 600; |
||||
|
margin-bottom: 3px; |
||||
|
// color: #c63243; |
||||
|
|
||||
|
} |
||||
|
.tips { |
||||
|
text-align: center; |
||||
|
white-space: nowrap; |
||||
|
margin-top: 10px; |
||||
|
font-size: 0.22rem; |
||||
|
} |
||||
|
|
||||
|
.goAI { |
||||
|
font-weight: 600; |
||||
|
color: #ff0000; |
||||
|
margin-top: 10px; |
||||
|
text-decoration-line: underline; |
||||
|
font-size: 0.24rem; |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
.scroll-box { |
||||
|
width: 87%; |
||||
|
height: 7rem; |
||||
|
left: 0rem; |
||||
|
right: 0rem; |
||||
|
position: relative; |
||||
|
margin-top: 0.5rem; |
||||
|
// display: flex; |
||||
|
// flex-direction: column; |
||||
|
// align-items: center; |
||||
|
background-color: #fff; |
||||
|
|
||||
|
box-sizing: border-box; |
||||
|
padding:15px; |
||||
|
border-radius: 10px; |
||||
|
|
||||
|
.title { |
||||
|
color: #c63243; |
||||
|
font-size: 0.32rem; |
||||
|
font-weight: 600; |
||||
|
text-align: center; |
||||
|
margin-bottom: 15px; |
||||
|
} |
||||
|
.comment-box { |
||||
|
width: 100%; |
||||
|
height: 5.7rem; |
||||
|
// position: relative; |
||||
|
// overflow:hidden; |
||||
|
.comment-item { |
||||
|
width: 100%; |
||||
|
// height: 1.5rem; |
||||
|
height: 200px; |
||||
|
// position: relative; |
||||
|
box-sizing: border-box; |
||||
|
padding:10px 10px 10px 70px; |
||||
|
background-color: #fef9e5; |
||||
|
border-radius: 10px; |
||||
|
margin-bottom: 10px; |
||||
|
.user-head { |
||||
|
left: 25px; |
||||
|
position: absolute; |
||||
|
width: 50px; |
||||
|
height: 50px; |
||||
|
border-radius: 50%; |
||||
|
background-color: #c63243; |
||||
|
// display: inline-block; |
||||
|
} |
||||
|
.user-name { |
||||
|
font-size: 0.3rem; |
||||
|
color: #c63243; |
||||
|
font-weight: 600; |
||||
|
// margin-bottom: 8px; |
||||
|
|
||||
|
} |
||||
|
.comment { |
||||
|
font-size: 0.26rem; |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,60 @@ |
|||||
|
<template> |
||||
|
<div class="privacy-wrap"> |
||||
|
<h3>个人信息授权与保护声明</h3> |
||||
|
<br> |
||||
|
<p>尊敬的用户,“”及其关联公司(以下简称“我们”)将按照本声明及《隐私权保护政策》的规定收集、保存、使用、储存、分享、披露及保护您的个人信息。因此请您务必认真完整阅读并理解本声明,尤其是黑体加粗的部分,如果您不同意本声明,请勿进行下一步操作。</p> |
||||
|
</br><p> |
||||
|
</br>一、 我们收集和使用您的个人信息类型和目的</br></br> |
||||
|
1、为给您提供完善的服务,需要您向我们提供一些信息,我们收集您的个人信息的最终目的是为了向您提供更好的产品、服务,优化并丰富您的用户体验,这些个人信息系能够单独或者与其他信息结合识别您的个人身份的信息,包括但不限于: |
||||
|
</br>(1)姓名</br> |
||||
|
(2)手机号码</br> |
||||
|
(3) 您在服务提供方所建落地页面输入或上载的其他个人信息。</br> |
||||
|
</br>2、您授权我们将上述信息共享给您在浏览界面所看到的特定行业对应的服务提供方,之后您会收到来自该服务提供方的电话或短信,以向您提供相关服务的邀请或需求沟通,包含但不限于: |
||||
|
</br>(1)汽车行业服务提供方,邀请您试驾、到 4s 店看车、参与车友会活动;</br> |
||||
|
(2)教育行业服务提供方,邀请您试听课程、沟通课程需求;</br> |
||||
|
(3)旅游行业服务提供方,与您预约沟通自由行需求,或沟通定制游需求;</br> |
||||
|
(4)家装行业服务提供方,与您预约上门测量、预约设计师沟通装修需求;</br> |
||||
|
(5)其他需要联系您,以便您接受线下服务,实地体验的场景。</br> |
||||
|
</br>3、当您使用在线通话服务时,为了保证服务方的服务质量,您的通话可能会被录音。如您对此有所异议,请您不要点击“电话”按钮。 |
||||
|
</br></br>4、以上个人信息均是您自愿提供,如果您拒绝同意提供的,将无法使用该产品功能,但不会影响您正常使用其它功能。 |
||||
|
</br></br>5、对于不满 18 周岁的用户,须在其法定监护人已经阅读本政策并且许可的情况下,通过网站提交个人信息。 |
||||
|
</br></br>二、 我们如何使用及共享您的个人信息</br> |
||||
|
</br>1、您同意我们通过如下方式使用及对外共享您个人信息的情况(包含对于个人信息的存储和处理): |
||||
|
</br>1) 我们在合法正当的范围内使用;</br> |
||||
|
2) 我们向您授权的服务提供方分享并由其在合法正当的范围内使用;</br> |
||||
|
3) 我们及相关特定行业的服务提供方为满足您的需求,可能会通过您提供的信息与您联系;</br> |
||||
|
4)为了省去您手动输入的操作,您用于注册的手机号可能已经展示在信息录入界面,但这并不代表第三方已经获取相关信息。当且仅当在同意《个人信息授权与保护声明》的前提下,我方获得您授权与第三方分享您的相关信息(具体授权信息类型以页面提示为准)的许可后,我方才会向第三方办法访问您信息的令牌。若您拒绝使用预填充功能,或者拟撤回使用预填充功能的授权,不影响您主动输入相关信息并继续使用第三方的产品/服务 |
||||
|
</br>5)我们及您授权范围内的服务提供方可能定期或不定期向您发送有关产品、服务或相关活动的信息,您同意接收上述信息。当我们超出与本声明及《隐私权保护政策》所声称的目的具有直接或合理关联的范围后使用您的个人信息的,我们会再次向您告知并征得您的同意。您同意免除上述个人信息的接收和/或使用方在按照本声明所述情形下进行信息披露和使用而导致的或可能导致的所有索赔、责任和损失 |
||||
|
</br></br>2、我们已在相应的功能模块明示征得了您的同意。我们已经要求其应对您的个人信息进行严格保密,要求其按照我们的说明、《隐私权保护政策》以及其他任何相关的保密和安全措施来处理个人信息。 |
||||
|
</br></br>3、在个人信息匿名化或去标识化的前提下,本平台有权对您提供的个人信息进行数据分析,并对用户数据库加以商业化使用。 |
||||
|
</br></br>三、 更正或投诉</br> |
||||
|
</br>如果您需要查询、修改或更正、撤销授权您的个人信息,或对个人信息保护问题有任何疑问或投诉,您可以通过以下方式联系我们:拨打电话400-8823-016。 |
||||
|
</br></br>四、 通知和修订 |
||||
|
</br>我们可能适时修改本声明,对于重大变更,我们会提供更显著的通知,您可以选择停止使用提供的产品/服务;在该种情况下,如您仍然继续使用我们的产品/服务,即表示同意接受经修订的本声明及《隐私权保护政策》的约束。 |
||||
|
</p> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
|
||||
|
created(){ |
||||
|
document.documentElement.scrollTop = 0; |
||||
|
document.title = "隐私协议"; |
||||
|
}, |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
</script> |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
.privacy-wrap { |
||||
|
padding: 10px; |
||||
|
font-size: 16px; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,461 @@ |
|||||
|
<template> |
||||
|
<div class="recieveVip-wrap"> |
||||
|
|
||||
|
<!-- 权益列表 --> |
||||
|
<div class="vip-box"> |
||||
|
<div class="get-title">请选择您要领取的会员月卡</div> |
||||
|
<div class="vip-list"> |
||||
|
<div class="vip-item" v-for="(item, index) in vipList" :key="index" @click="selectVip(index)"> |
||||
|
<div class="vip-icon" :class="curVipIndex == index? 'active' : ''" |
||||
|
:style=" `background: url(${item.icon}) no-repeat;background-size: 100% 100%;`"></div> |
||||
|
<!-- <div class="vip-name">{{ item.name }}</div> --> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<!-- 手机号输入框 --> |
||||
|
<div class="mid-box" > |
||||
|
<div class="cls_div_phone_input"> |
||||
|
<input class="cls_input_phone" v-model="mobile" type="text" maxlength="11" placeholder="请输入您的手机号"> |
||||
|
<img class="phone-icon" src="https://img.bnyer.cn/vip/hotAIphone.png" alt=""> |
||||
|
</div> |
||||
|
<img class="cls_img_btn" @click="clickMainButton()" src="https://img.bnyer.cn/vip/main-button.png"> |
||||
|
</div> |
||||
|
<!-- 资费 --> |
||||
|
<!-- <div class="price">业务资费:19.9元 / 月</div> --> |
||||
|
<!-- 规则 --> |
||||
|
<div class="rule-box"> |
||||
|
<div class="rule-icon"></div> |
||||
|
<div class="rule-content"> |
||||
|
[商品名称] :惠点生活 <br/> |
||||
|
[计费方式] : 支付宝连续包月<br/> |
||||
|
[商品权益说明] :<br/> |
||||
|
用户每月可领取腾讯视频月卡、爱奇艺月卡、优酷月卡、芒果TV月卡、哗哩哗哩大会员月卡、网易云音乐月卡、喜马拉雅会员月卡、知乎盐选会员月卡、饿了么会员月卡、百度网盘会员月卡中的任意一张。<br/> |
||||
|
[领取方式]:<br/> |
||||
|
本产品订购生效后,用户需要通过关注【次元意境】微信公众号,[会员福利 - 会员月月领] 入口及时领取权益,领取成功后1小时到账。凭订购手机号登录相应APP即可享受会员权益。<br/> |
||||
|
|
||||
|
[注意事项]:<br/> |
||||
|
1.权益领取成功后当月内不能进行退订、更改;<br/> |
||||
|
2.订购生效后凭订购手机号可每月领取会员一次,不可结转与转赠,当月不领取则视为自动放弃当月领取资格;<br/> |
||||
|
3.如您在权益充值未到账期间退订产品,将会导致权益充值失败。<br/> |
||||
|
[退订方式]:<br/> |
||||
|
进入支付宝APP---右下方“我的”---右上方的齿轮进入设置页面---点击“支付设置”---点击“免密支付/自动扣款”---选择“惠点生活”---点击“关闭服务”即可完成退订。<br/> |
||||
|
[联系我们]:<br/> |
||||
|
致电客服热线: 19983417235,客服在线时间:9:00-18:00。 |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="confirm-wrap" v-if="showPop"> |
||||
|
<div class="confirm-box"> |
||||
|
<div class="close-button" @click="isShowPop()">×</div> |
||||
|
<div class="confirm-title">确认领取<br/>【{{ vipList[curVipIndex].name}}】月卡吗?<br/><br/> |
||||
|
领取手机号:{{ mobile }}</div> |
||||
|
<div class="icon" :style=" `background: url(${vipList[curVipIndex].icon}) no-repeat;background-size: 100% 100%;`"></div> |
||||
|
<div class="confirm-button" @click="receiveRights()">确认</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import { Indicator, Toast } from "mint-ui"; |
||||
|
export default { |
||||
|
data() { |
||||
|
return{ |
||||
|
curVipIndex: 0, |
||||
|
mobile: '', |
||||
|
showPop: false, |
||||
|
canClick: true, |
||||
|
vipList: [ |
||||
|
{ |
||||
|
name: '优酷黄金会员', |
||||
|
icon: 'https://img.bnyer.cn/vip/youku.png', |
||||
|
vipKey: '10000281' |
||||
|
}, |
||||
|
{ |
||||
|
name: '爱奇艺黄金会员', |
||||
|
icon: 'https://img.bnyer.cn/vip/aiqiyi.png', |
||||
|
vipKey: '10000260' |
||||
|
}, |
||||
|
{ |
||||
|
name: '腾讯视频VIP会员', |
||||
|
icon: 'https://img.bnyer.cn/vip/tcenttv.png', |
||||
|
vipKey: '10000224' |
||||
|
}, |
||||
|
{ |
||||
|
name: '芒果TV全屏会员', |
||||
|
icon: 'https://img.bnyer.cn/vip/mangotv.png', |
||||
|
vipKey: '10000271' |
||||
|
}, |
||||
|
{ |
||||
|
name: '哔哩哔哩大会员', |
||||
|
icon: 'https://img.bnyer.cn/vip/bili.png', |
||||
|
vipKey: '10000257' |
||||
|
}, |
||||
|
|
||||
|
{ |
||||
|
name: '网易云音乐黑胶VIP', |
||||
|
icon: 'https://img.bnyer.cn/vip/wangyiyun.png', |
||||
|
vipKey: '10000298' |
||||
|
}, |
||||
|
{ |
||||
|
name: '饿了么超级会员', |
||||
|
icon: 'https://img.bnyer.cn/vip/eleme.png', |
||||
|
vipKey: '10000377' |
||||
|
}, |
||||
|
{ |
||||
|
name: '搜狐视频会员月卡', |
||||
|
icon: 'https://img.bnyer.cn/vip/ximalaya.png', |
||||
|
vipKey: '10000253' |
||||
|
}, |
||||
|
|
||||
|
{ |
||||
|
name: '知乎盐选会员月卡', |
||||
|
icon: 'https://img.bnyer.cn/vip/%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20230804224645.png', |
||||
|
vipKey: '10000440' |
||||
|
}, |
||||
|
|
||||
|
{ |
||||
|
name: '百度网盘普通会员', |
||||
|
icon: 'https://img.bnyer.cn/vip/baidu.png', |
||||
|
vipKey: '10000437' |
||||
|
}, |
||||
|
|
||||
|
|
||||
|
] |
||||
|
} |
||||
|
}, |
||||
|
created(){ |
||||
|
document.documentElement.scrollTop = 0; |
||||
|
document.title = "会员月月领"; |
||||
|
}, |
||||
|
|
||||
|
mounted() { |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
methods: { |
||||
|
selectVip(index) { |
||||
|
this.curVipIndex = index |
||||
|
}, |
||||
|
isShowPop() { |
||||
|
this.showPop = !this.showPop |
||||
|
}, |
||||
|
clickMainButton() { |
||||
|
if(this.mobile) { |
||||
|
var myreg = /^[1][3,4,5,7,8,9][0-9]{9}$/; |
||||
|
if (!myreg.test(this.mobile)) { |
||||
|
Toast('请输入正确的手机号~') |
||||
|
return |
||||
|
} |
||||
|
} else { |
||||
|
Toast('请输入手机号~') |
||||
|
return |
||||
|
} |
||||
|
this.isShowPop() |
||||
|
}, |
||||
|
|
||||
|
// 领取权益 |
||||
|
receiveRights(){ |
||||
|
|
||||
|
Indicator.open('领取中...') |
||||
|
|
||||
|
// 查询余额 |
||||
|
|
||||
|
let parms = { |
||||
|
chargeAccountNumber: this.mobile, |
||||
|
skuId: this.vipList[this.curVipIndex].vipKey, |
||||
|
chargeAccountType:10 |
||||
|
} |
||||
|
|
||||
|
this.axios({ |
||||
|
method: "post", |
||||
|
url: `https://interface.bnyer.cn/yunmei/directBuy`, |
||||
|
// url: `http://192.168.2.8:8086/yunmei/directBuy`, |
||||
|
data: parms |
||||
|
}).then((rsp) => { |
||||
|
|
||||
|
console.log(rsp); |
||||
|
if(rsp.code == 0) { |
||||
|
|
||||
|
|
||||
|
if(rsp.res.code == '000000'){ |
||||
|
Indicator.close(); |
||||
|
this.isShowPop() |
||||
|
this.mobile = '' |
||||
|
this.curVipIndex = 0 |
||||
|
|
||||
|
Toast({ |
||||
|
message: "领取成功,充值过程存在一定延时,请稍后前往对应APP查看~", |
||||
|
}) |
||||
|
|
||||
|
|
||||
|
} else if(rsp.res.code == '10024' || rsp.res.code == '10026'){ |
||||
|
Indicator.close(); |
||||
|
this.isShowPop() |
||||
|
this.mobile = '' |
||||
|
this.curVipIndex = 0 |
||||
|
Toast({ |
||||
|
message: "您暂无领取资格", |
||||
|
}) |
||||
|
} else if(rsp.res.code == '10025'){ |
||||
|
Indicator.close(); |
||||
|
this.isShowPop() |
||||
|
this.mobile = '' |
||||
|
this.curVipIndex = 0 |
||||
|
Toast({ |
||||
|
message: "您当月已领取过权益,请下月再来~", |
||||
|
}) |
||||
|
} else { |
||||
|
Indicator.close(); |
||||
|
this.isShowPop() |
||||
|
this.mobile = '' |
||||
|
this.curVipIndex = 0 |
||||
|
Toast({ |
||||
|
message: "网络异常,请稍后再试~", |
||||
|
}) |
||||
|
} |
||||
|
}else { |
||||
|
Indicator.close(); |
||||
|
this.isShowPop() |
||||
|
this.mobile = '' |
||||
|
this.curVipIndex = 0 |
||||
|
Toast({ |
||||
|
message: "网络异常,请稍后再试~", |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
}) |
||||
|
|
||||
|
|
||||
|
|
||||
|
.catch((err)=>{ |
||||
|
Indicator.close(); |
||||
|
this.isShowPop() |
||||
|
this.mobile = '' |
||||
|
this.curVipIndex = 0 |
||||
|
Toast({ |
||||
|
message: "系统错误,请联系客服~", |
||||
|
}); |
||||
|
}) |
||||
|
|
||||
|
}, |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
.recieveVip-wrap { |
||||
|
width: 100%; |
||||
|
height: auto; |
||||
|
position: absolute; |
||||
|
background-color: #fb986e; |
||||
|
padding-bottom: 3rem; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
align-items: center; |
||||
|
overflow-x: hidden; |
||||
|
overflow-y: scroll; |
||||
|
background-image: url('https://img.bnyer.cn/vip/get-top-img.png'); |
||||
|
background-size: 100% 15rem; |
||||
|
background-repeat: no-repeat; |
||||
|
|
||||
|
.fixed { |
||||
|
position: fixed !important; |
||||
|
bottom: 0rem !important; |
||||
|
left: 0; |
||||
|
right: 0; |
||||
|
// z-index: 100; |
||||
|
transform: scale(0.8); |
||||
|
margin-top: 0rem !important; |
||||
|
} |
||||
|
|
||||
|
.confirm-wrap { |
||||
|
// z-index: 100; |
||||
|
position: fixed; |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
background-color: rgba($color: #000000, $alpha: 0.7); |
||||
|
} |
||||
|
.confirm-box { |
||||
|
position: absolute; |
||||
|
width: 80%; |
||||
|
height: 7rem; |
||||
|
border: 3px solid #f37151; |
||||
|
background-color: rgb(244, 234, 222); |
||||
|
border-radius: 10px; |
||||
|
top: 50%; |
||||
|
left: 50%; |
||||
|
transform: translate(-50%, -50%); |
||||
|
padding: 20px 0px; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
align-items: center; |
||||
|
justify-content: space-around; |
||||
|
.close-button { |
||||
|
font-size: 35px; |
||||
|
position: absolute; |
||||
|
right: 5px; |
||||
|
top: -8px; |
||||
|
color: #a73a1e; |
||||
|
} |
||||
|
.confirm-title { |
||||
|
font-size: 16px; |
||||
|
font-weight: bold; |
||||
|
color: #a73a1e; |
||||
|
text-align: center; |
||||
|
} |
||||
|
.icon { |
||||
|
width: 2rem; |
||||
|
height: 2rem; |
||||
|
// background-color: #fb986e; |
||||
|
border-radius: 8px; |
||||
|
} |
||||
|
.confirm-button { |
||||
|
background: linear-gradient(#fb986e, #d7502f); |
||||
|
width:4rem; |
||||
|
height: 1rem; |
||||
|
border-radius: 50px; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
color: #fff; |
||||
|
font-size: 20px; |
||||
|
font-weight: bold; |
||||
|
} |
||||
|
} |
||||
|
.vip-box { |
||||
|
margin-top: 3.1rem; |
||||
|
width: 90%; |
||||
|
height: auto; |
||||
|
background-color: antiquewhite; |
||||
|
border-radius: 20px; |
||||
|
padding: 15px; |
||||
|
box-sizing: border-box; |
||||
|
.get-title { |
||||
|
font-size: 16px; |
||||
|
font-weight: bold; |
||||
|
text-align: center; |
||||
|
margin-bottom: 15px; |
||||
|
} |
||||
|
.vip-list { |
||||
|
display: flex; |
||||
|
flex-wrap: wrap; |
||||
|
justify-content: space-between; |
||||
|
// align-items: center; |
||||
|
.active { |
||||
|
border: 5px solid #dc2c00; |
||||
|
} |
||||
|
.vip-item { |
||||
|
width: 18%; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
align-items: center; |
||||
|
margin-bottom: 10px; |
||||
|
.vip-icon { |
||||
|
// border-radius: 5px; |
||||
|
width: 100%; |
||||
|
height: 1.11rem; |
||||
|
background-color: #fff; |
||||
|
margin-bottom: 4px; |
||||
|
box-sizing: border-box; |
||||
|
} |
||||
|
.vip-name { |
||||
|
width: 100%; |
||||
|
text-align: center; |
||||
|
white-space: wrap; |
||||
|
font-size: 10px; |
||||
|
line-height: 12px; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.mid-box { |
||||
|
// z-index: 100; |
||||
|
left: 0rem; |
||||
|
right: 0rem; |
||||
|
position: relative; |
||||
|
margin-top: 0.5rem; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
align-items: center; |
||||
|
|
||||
|
.cls_div_phone_input { |
||||
|
height: 1rem; |
||||
|
width: 7rem; |
||||
|
position: relative; |
||||
|
.phone-icon { |
||||
|
width: 0.6rem; |
||||
|
position: absolute; |
||||
|
top: 0.27rem; |
||||
|
left: 0.8rem; |
||||
|
// z-index: 1; |
||||
|
} |
||||
|
.cls_input_phone { |
||||
|
position: relative; |
||||
|
left: 50%; |
||||
|
transform: translateX(-50%); |
||||
|
height: 1.1rem; |
||||
|
width: 5rem; |
||||
|
border-radius: 50px; |
||||
|
padding-left: 1.5rem; |
||||
|
font-size: 0.4rem; |
||||
|
background-color: white; |
||||
|
border: none; |
||||
|
} |
||||
|
} |
||||
|
.cls_img_btn { |
||||
|
margin-top: 0.4rem; |
||||
|
position: relative; |
||||
|
width: 6rem; |
||||
|
height: 1.6rem; |
||||
|
animation: btnScaleAnim 1s infinite; |
||||
|
@keyframes btnScaleAnim { |
||||
|
0%{ |
||||
|
transform: scale(0.9); |
||||
|
} |
||||
|
50% { |
||||
|
transform: scale(0.95); |
||||
|
} |
||||
|
100% { |
||||
|
transform: scale(0.9); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.price { |
||||
|
text-align: center; |
||||
|
color: #fff; |
||||
|
font-size: 11px; |
||||
|
} |
||||
|
.rule-box { |
||||
|
margin-top: 0.4rem; |
||||
|
position: relative; |
||||
|
width: 86%; |
||||
|
// height: 12rem; |
||||
|
background-color: #f37151; |
||||
|
border-radius: 10px; |
||||
|
padding: 12px 18px; |
||||
|
box-sizing: border-box; |
||||
|
.rule-icon { |
||||
|
background-image: url('https://img.bnyer.cn/vip/rule-icon.png'); |
||||
|
background-size: 100% 100%; |
||||
|
width: 1.7rem; |
||||
|
height: 0.6rem; |
||||
|
} |
||||
|
|
||||
|
.rule-content { |
||||
|
margin-top: 10px; |
||||
|
// line-height: 15px; |
||||
|
font-size: 0.22rem; |
||||
|
color: #FFF; |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,512 @@ |
|||||
|
<template> |
||||
|
<div class="hotVipV2-wrap"> |
||||
|
<!-- 头图 --> |
||||
|
<div class="top-img"></div> |
||||
|
<div class="scroll-wrap"> |
||||
|
<div class="scroll-box" > |
||||
|
<div class="scroll-item" v-for="(item, index) in scrollArr" :key="index">{{item}}</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<!-- 手机号输入框 --> |
||||
|
<div class="mid-box" > |
||||
|
<div class="cls_div_phone_input"> |
||||
|
<input class="cls_input_phone" ref="phoneInput" v-model="mobile" type="tel" maxlength="11" placeholder="请输入手机号码"> |
||||
|
</div> |
||||
|
<img class="cls_img_btn" @click="aiThreePay()" src="https://img.bnyer.cn/vip/vip-btn.gif"> |
||||
|
|
||||
|
|
||||
|
<!-- 隐私协议 --> |
||||
|
<div class="privacy-box"> |
||||
|
<img v-if="!agreePrivacy" @click="clickAgreePrivacy()" src="https://ydsh0516.cjdsp.com/ydshh5s/static/images-gd/ic-select-not.png" class="selectBox" /> |
||||
|
<img v-if="agreePrivacy" @click="clickAgreePrivacy()" src="https://ydsh0516.cjdsp.com/ydshh5s/static/images-gd/ic-select.png" class="selectBox" /> |
||||
|
|
||||
|
我已阅读并同意下方活动规则、 |
||||
|
<span class="cls_sp_procotol_2" @click="goLookPrivacy()"> 隐私条款 </span>等协议 |
||||
|
</div> |
||||
|
<!-- 资费 --> |
||||
|
<div class="price" style="margin-top:0.05rem;">业务资费:19.9元/月 </div> |
||||
|
|
||||
|
|
||||
|
<!-- <div class="price"></div> --> |
||||
|
</div> |
||||
|
<!-- 规则 --> |
||||
|
<div class="rule-box"> |
||||
|
<div class="rule-icon">活动规则</div> |
||||
|
<div class="rule-content"> |
||||
|
[商品名称] :惠点生活 <br/> |
||||
|
[计费方式] : 支付宝连续包月<br/> |
||||
|
[商品权益说明] :<br/> |
||||
|
用户每月可领取腾讯视频月卡、爱奇艺月卡、优酷月卡、芒果TV月卡、哗哩哗哩大会员月卡、网易云音乐月卡、喜马拉雅会员月卡、知乎盐选会员月卡、饿了么会员月卡、百度网盘会员月卡中的任意一张。<br/> |
||||
|
[领取方式]:<br/> |
||||
|
本产品订购生效后,用户需要通过关注【次元意境】微信公众号,[会员福利 - 会员月月领] 入口及时领取权益,领取成功后1小时到账。凭订购手机号登录相应APP即可享受会员权益。<br/> |
||||
|
[注意事项]:<br/> |
||||
|
1.权益领取成功后当月内不能进行退订、更改;<br/> |
||||
|
2.订购生效后凭订购手机号可每月领取会员一次,不可结转与转赠,当月不领取则视为自动放弃当月领取资格;<br/> |
||||
|
3.如您在权益充值未到账期间退订产品,将会导致权益充值失败。<br/> |
||||
|
[退订方式]:<br/> |
||||
|
进入支付宝APP---右下方“我的”---右上方的齿轮进入设置页面---点击“支付设置”---点击“免密支付/自动扣款”---选择“惠点生活”---点击“关闭服务”即可完成退订。<br/> |
||||
|
[联系我们]:<br/> |
||||
|
致电客服热线:19983417235,客服在线时间:9:00-18:00。 |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
|
||||
|
|
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import { Toast, Indicator } from "mint-ui"; |
||||
|
export default { |
||||
|
data() { |
||||
|
return{ |
||||
|
scrollTop: 0, |
||||
|
phoneFixed: false, |
||||
|
mobile: '', |
||||
|
lid: 0, |
||||
|
channelType: null, |
||||
|
canClick: true, |
||||
|
showPop: false, |
||||
|
agreePrivacy: false, |
||||
|
appkey: null, |
||||
|
scrollArr:[ |
||||
|
'151****2290已领取优酷视频会员', |
||||
|
'135****7952已领取爱奇艺会员', |
||||
|
'132****1506已领取腾讯视频会员', |
||||
|
'189****7756已领取芒果TV会员', |
||||
|
'180****6543已领取哔哩哔哩会员', |
||||
|
'181****2234已领取网易云音乐会员', |
||||
|
'134****8775已领取饿了么会员', |
||||
|
'132****1355已领取喜马拉雅听书会员', |
||||
|
'189****2293已领取百度网盘会员', |
||||
|
'153****9412已领取知乎盐选会员', |
||||
|
'172****5644已领取优酷视频会员', |
||||
|
'185****7885已领取爱奇艺会员', |
||||
|
'199****9877已领取腾讯视频会员', |
||||
|
'175****7655已领取芒果TV会员', |
||||
|
'156****3455已领取哔哩哔哩会员', |
||||
|
'145****1135已领取网易云音乐会员', |
||||
|
'175****2231已领取饿了么会员', |
||||
|
'137****9122已领取喜马拉雅听书会员', |
||||
|
'177****4277已领取百度网盘会员', |
||||
|
'189****7952已领取知乎盐选会员', |
||||
|
], |
||||
|
|
||||
|
} |
||||
|
}, |
||||
|
created(){ |
||||
|
document.documentElement.scrollTop = 0; |
||||
|
document.title = "会员权益随心选"; |
||||
|
}, |
||||
|
watch:{ |
||||
|
'mobile' : { |
||||
|
handler(value) { |
||||
|
this.checkPhone(value) |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
mounted() { |
||||
|
this.getUrlParam() |
||||
|
}, |
||||
|
|
||||
|
|
||||
|
methods: { |
||||
|
// 同意隐私授权 |
||||
|
clickAgreePrivacy() { |
||||
|
this.agreePrivacy = !this.agreePrivacy |
||||
|
}, |
||||
|
goLookPrivacy() { |
||||
|
window.open ("https://rights.bnyer.cn/#/privacy") |
||||
|
}, |
||||
|
|
||||
|
// 手机号居底 |
||||
|
handleScroll() { |
||||
|
const scrollTop = window.scrollY || document.documentElement.scrollTop; |
||||
|
if (scrollTop > this.scrollTop + 50) { |
||||
|
this.phoneFixed = true; |
||||
|
} else { |
||||
|
this.phoneFixed = false; |
||||
|
} |
||||
|
}, |
||||
|
// 获取lid |
||||
|
getUrlParam() { |
||||
|
this.lid = this.$route.query.id; |
||||
|
this.channelType = this.$route.query.type; |
||||
|
console.log(this.lid); |
||||
|
console.log(this.channelType); |
||||
|
|
||||
|
// if(this.channelType == 'llg') { |
||||
|
// this.getLLGAppKey() |
||||
|
// } else { |
||||
|
// this.getAppKey() |
||||
|
// } |
||||
|
// ta |
||||
|
if(this.lid == '1160') { |
||||
|
this.getTAAppKey() |
||||
|
} |
||||
|
}, |
||||
|
// ta |
||||
|
getTAAppKey() { |
||||
|
// this.appkey = location.search.replace(/^\?/, '') + location.hash.replace(/^\#/, '&') |
||||
|
this.appkey = this.$route.query.a_oId; |
||||
|
}, |
||||
|
// llg |
||||
|
getLLGAppKey() { |
||||
|
this.appkey = this.$route.query.llgclickid; |
||||
|
}, |
||||
|
// gdt tt |
||||
|
getAppKey() { |
||||
|
this.appkey = ""; |
||||
|
|
||||
|
let testNew = window.location.hash; |
||||
|
let testsNew = decodeURIComponent(testNew); |
||||
|
console.log(testsNew); |
||||
|
this.union_site = ((testsNew || '').split("&")[1] || '').split("=")[1]; |
||||
|
|
||||
|
var test = window.location.search; |
||||
|
|
||||
|
var tests = decodeURIComponent(test); |
||||
|
|
||||
|
var clickid; |
||||
|
var dkey; |
||||
|
|
||||
|
if (tests.indexOf("?") != -1) { |
||||
|
var str = tests.substr(1); |
||||
|
var strs = str.split("&"); |
||||
|
console.log(strs,'打印strs'); |
||||
|
// console.log(strs); |
||||
|
for (var i = 0; i < strs.length; i++) { |
||||
|
// Request.push(strs[i].split("=")) |
||||
|
// console.log(strs[i].split("=")); |
||||
|
if ( |
||||
|
strs[i].split("=")[0] == "clickid" || |
||||
|
strs[i].split("=")[0] == "clickid " || |
||||
|
strs[i].split("=")[1] == "clickid" || |
||||
|
strs[i].split("=")[0] == "qz_gdt" || |
||||
|
strs[i].split("=")[0] == "gdt_vid" || |
||||
|
strs[i].split("=")[0] == "llgclickid" |
||||
|
) { |
||||
|
clickid = strs[i].split("=")[1]; |
||||
|
// console.log(clickid); |
||||
|
// console.log(clickid) |
||||
|
this.appkey = clickid; |
||||
|
console.log('打印this.appkey===',clickid,); |
||||
|
// alert(this.appkey) |
||||
|
// alert(this.appkey,"344444444444444444444444") |
||||
|
} |
||||
|
if ( |
||||
|
strs[i].split("=")[0] == "adid" || |
||||
|
strs[i].split("=")[0] == "adid " |
||||
|
) { |
||||
|
dkey = strs[i].split("=")[1]; |
||||
|
// console.log(dkey, '0000000000000000000000') |
||||
|
this.dkey = dkey; |
||||
|
console.log(this.dkey); |
||||
|
// alert(this.dkey,"566666666666666666666666") |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
// console.log(this.appkey); |
||||
|
}, |
||||
|
|
||||
|
// 手机号末尾判断 |
||||
|
checkPhone(mobile) { |
||||
|
if(mobile.length == 11) { |
||||
|
this.agreePrivacy = true |
||||
|
var myreg = /^[1][3,4,5,7,8,9][0-9]{9}$/; |
||||
|
if (!myreg.test(this.mobile)) { |
||||
|
Toast('请输入正确的手机号') |
||||
|
return |
||||
|
} else { |
||||
|
this.aiThreePay() |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
// 开通 |
||||
|
aiThreePay() { |
||||
|
// 手机号校验 |
||||
|
if(this.mobile) { |
||||
|
var myreg = /^[1][3,4,5,7,8,9][0-9]{9}$/; |
||||
|
if (!myreg.test(this.mobile)) { |
||||
|
Toast('请输入正确的手机号') |
||||
|
return |
||||
|
} |
||||
|
} else { |
||||
|
Toast('请输入正确的手机号') |
||||
|
return |
||||
|
} |
||||
|
if(!this.agreePrivacy) { |
||||
|
Toast('请阅读并同意隐私协议') |
||||
|
return |
||||
|
} |
||||
|
// 防连点 |
||||
|
if(!this.canClick) return |
||||
|
// 加载中 |
||||
|
Indicator.open('领取中...') |
||||
|
this.canClick = false |
||||
|
// 参数 |
||||
|
const data = { |
||||
|
mobile: this.mobile, |
||||
|
linkId: this.lid, |
||||
|
openAddress: this.appkey, |
||||
|
// channelType: this.channelType |
||||
|
} |
||||
|
this.axios({ |
||||
|
method: "post", |
||||
|
url:"https://interface.bnyer.cn/alipay/signUp", |
||||
|
// url: `http://192.168.2.8:8086/alipay/signUp`, |
||||
|
data: data |
||||
|
}).then((res) => { |
||||
|
Indicator.close() |
||||
|
this.canClick = true |
||||
|
if(res.code == 0){ |
||||
|
// 跳转支付宝 |
||||
|
window.location.href = res.result |
||||
|
} else if (res.code == '10031') { |
||||
|
Toast('您当前已开通,请勿重复开通~') |
||||
|
} else if (res.code == '10033') { |
||||
|
// 黑名单用户 |
||||
|
Toast('网络繁忙,请稍后再试~') |
||||
|
} else{ |
||||
|
Toast('网络繁忙,请稍后再试~') |
||||
|
} |
||||
|
|
||||
|
}) |
||||
|
}, |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss"> |
||||
|
.mint-indicator-wrapper { |
||||
|
z-index: 9999; |
||||
|
} |
||||
|
</style> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
|
||||
|
|
||||
|
.hotVipV2-wrap { |
||||
|
width: 100%; |
||||
|
height: auto; |
||||
|
position: absolute; |
||||
|
background-color: #e53c51; |
||||
|
padding-bottom: 2rem; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
align-items: center; |
||||
|
overflow-x: hidden; |
||||
|
overflow-y: scroll; |
||||
|
|
||||
|
|
||||
|
.top-img { |
||||
|
background-image: url('https://img.bnyer.cn/vip/banner.jpg'); |
||||
|
background-size: 100% 100%; |
||||
|
width: 100%; |
||||
|
// height: 360px; |
||||
|
height: 6.8rem; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
.scroll-wrap { |
||||
|
margin-top: 10px; |
||||
|
width: 100%; |
||||
|
// overflow: hidden; |
||||
|
animation: 20s goleft linear infinite normal; |
||||
|
@keyframes goleft { |
||||
|
from { |
||||
|
transform: translateX(0); |
||||
|
} |
||||
|
to { |
||||
|
transform: translateX(-100%); |
||||
|
} |
||||
|
} |
||||
|
.scroll-box { |
||||
|
// width: 5100px; |
||||
|
width: auto; |
||||
|
display: flex; |
||||
|
|
||||
|
|
||||
|
.scroll-item { |
||||
|
flex-shrink: 0; |
||||
|
// width: 235px; |
||||
|
display: inline-block; |
||||
|
color: #fff; |
||||
|
background-color: rgba($color: #000000, $alpha: 0.25); |
||||
|
padding: 5px 25px; |
||||
|
text-align: center; |
||||
|
font-size: 0.25rem; |
||||
|
border-radius: 25px; |
||||
|
margin-right: 20px; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.fixed { |
||||
|
position: fixed !important; |
||||
|
bottom: 0rem !important; |
||||
|
left: 0.16rem !important; |
||||
|
right: 0; |
||||
|
z-index: 100; |
||||
|
transform: scale(0.8); |
||||
|
margin-top: 0rem !important; |
||||
|
} |
||||
|
|
||||
|
.mid-box { |
||||
|
// z-index: 100; |
||||
|
width: 87%; |
||||
|
left: 0rem; |
||||
|
right: 0rem; |
||||
|
position: relative; |
||||
|
margin-top: 0.5rem; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
align-items: center; |
||||
|
background-color: #fff; |
||||
|
|
||||
|
box-sizing: border-box; |
||||
|
padding:35px 0px; |
||||
|
border-radius: 10px; |
||||
|
// box-sizing: border-box; |
||||
|
|
||||
|
.cls_div_phone_input { |
||||
|
height: 1rem; |
||||
|
width: 7rem; |
||||
|
position: relative; |
||||
|
|
||||
|
.phone-icon { |
||||
|
width: 0.6rem; |
||||
|
position: absolute; |
||||
|
top: 0.18rem; |
||||
|
left: 1.1rem; |
||||
|
z-index: 1; |
||||
|
} |
||||
|
.cls_input_phone { |
||||
|
position: relative; |
||||
|
left: 50%; |
||||
|
transform: translateX(-50%); |
||||
|
height: 1rem; |
||||
|
width: 5.4rem; |
||||
|
border-radius: 20px; |
||||
|
padding-left: 20px; |
||||
|
box-sizing: border-box; |
||||
|
font-size: 0.32rem; |
||||
|
font-weight: bold; |
||||
|
// text-align: center; |
||||
|
background-color: white; |
||||
|
border: 2px solid red; |
||||
|
|
||||
|
// border: none; |
||||
|
} |
||||
|
} |
||||
|
.cls_img_btn { |
||||
|
margin-top: 0.2rem; |
||||
|
position: relative; |
||||
|
width: 5.2rem; |
||||
|
// height: 1rem; |
||||
|
// animation: btnScaleAnim 1s infinite; |
||||
|
@keyframes btnScaleAnim { |
||||
|
0%{ |
||||
|
transform: scale(0.9); |
||||
|
} |
||||
|
50% { |
||||
|
transform: scale(1); |
||||
|
} |
||||
|
100% { |
||||
|
transform: scale(0.9); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.price { |
||||
|
// font-weight: bold; |
||||
|
// margin-top: 0.25rem; |
||||
|
text-align: center; |
||||
|
color: rgba(0,0,0,0.9); |
||||
|
font-size: 0.22rem; |
||||
|
} |
||||
|
|
||||
|
.tips { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
font-weight: 600; |
||||
|
// margin-top: 0.25rem; |
||||
|
// text-align: center; |
||||
|
color: rgb(108, 1, 1); |
||||
|
font-size: 0.22rem; |
||||
|
margin-bottom: -0.2rem; |
||||
|
} |
||||
|
|
||||
|
.privacy-box { |
||||
|
color: rgba(0,0,0,0.9); |
||||
|
|
||||
|
margin-top: 0.2rem; |
||||
|
// margin-bottom: 0.2rem; |
||||
|
width: 100%; |
||||
|
z-index: 1; |
||||
|
// line-height: 0.25rem; |
||||
|
text-align: center; |
||||
|
// color: #fff6f3; |
||||
|
font-size: 0.22rem; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
.selectBox { |
||||
|
margin-right: 0.1rem; |
||||
|
|
||||
|
width: 0.26rem; |
||||
|
height: 0.26rem; |
||||
|
} |
||||
|
.cls_sp_procotol_2 { |
||||
|
// margin-left: 0.1rem; |
||||
|
// color: #fe7d4a; |
||||
|
// font-weight: bold; |
||||
|
// text-decoration: underline; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
.rule-box { |
||||
|
margin-top: 0.7rem; |
||||
|
position: relative; |
||||
|
width: 87%; |
||||
|
// height: 12rem; |
||||
|
background-color: #fdf9e3; |
||||
|
border-radius: 10px; |
||||
|
padding: 30px 18px; |
||||
|
box-sizing: border-box; |
||||
|
.rule-icon { |
||||
|
position: relative; |
||||
|
left: 50%; |
||||
|
transform: translateX(-50%); |
||||
|
// margin: 0 auto; |
||||
|
// background-image: url('https://vediocnd.corpring.com/hotVIP/rule-icon.png'); |
||||
|
// background-size: 100% 100%; |
||||
|
background-color: #ffc72c; |
||||
|
border-radius: 25px; |
||||
|
font-weight: bold; |
||||
|
font-size: 0.38rem; |
||||
|
padding: 8px 30px; |
||||
|
display: inline-block; |
||||
|
// width: auto; |
||||
|
// width: 1.7rem; |
||||
|
// height: 0.6rem; |
||||
|
} |
||||
|
.rule-content { |
||||
|
margin-top: 30px; |
||||
|
line-height: 15px; |
||||
|
font-size: 0.26rem; |
||||
|
line-height: 0.46rem; |
||||
|
// color: #FFF; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,64 @@ |
|||||
|
|
||||
|
|
||||
|
const CompressionWebpackPlugin = require("compression-webpack-plugin"); |
||||
|
|
||||
|
module.exports = { |
||||
|
lintOnSave: false, // 关闭eslint
|
||||
|
publicPath: './', |
||||
|
assetsDir: "static", |
||||
|
outputDir: process.env.VUE_APP_FLAG === 'pro'?"dist":"test", |
||||
|
devServer: { |
||||
|
// host: '127.0.0.1',
|
||||
|
host: '0.0.0.0', |
||||
|
port: 9529, |
||||
|
proxy: { |
||||
|
'/api': { |
||||
|
target: 'https://interface.douring.com', |
||||
|
changeOrigin: true, |
||||
|
pathRewrite: { |
||||
|
'/api': '' |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
productionSourceMap: false, |
||||
|
chainWebpack: (config) => { |
||||
|
config.plugins.delete('prefetch'); |
||||
|
}, |
||||
|
configureWebpack: { |
||||
|
plugins: [ |
||||
|
new CompressionWebpackPlugin({ |
||||
|
algorithm: 'gzip', // 使用gzip压缩
|
||||
|
test: /\.js$|\.html$|\.css$/, // 匹配文件名
|
||||
|
filename: '[path].gz[query]', // 压缩后的文件名(保持原文件名,后缀加.gz)
|
||||
|
minRatio: 1, // 压缩率小于1才会压缩
|
||||
|
threshold: 10240, // 对超过10k的数据压缩
|
||||
|
deleteOriginalAssets: false, // 是否删除未压缩的源文件,谨慎设置,如果希望提供非gzip的资源,可不设置或者设置为false(比如删除打包后的gz后还可以加载到原始资源文件)
|
||||
|
}), |
||||
|
], |
||||
|
performance: { |
||||
|
hints: 'warning', |
||||
|
// 入口起点的最大体积
|
||||
|
maxEntrypointSize: 50000000, |
||||
|
// 生成文件的最大体积
|
||||
|
maxAssetSize: 30000000, |
||||
|
// 只给出 js 文件的性能提示
|
||||
|
assetFilter: function (assetFilename) { |
||||
|
return assetFilename.endsWith('.js') |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
configureWebpack: config => { |
||||
|
config.module.rules.push({ |
||||
|
test: /\.worker.js$/, |
||||
|
use: { |
||||
|
loader: 'worker-loader', |
||||
|
options: { inline: true, name: 'workerName.[hash].js' } |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
parallel: false, |
||||
|
chainWebpack: config => { |
||||
|
config.output.globalObject('this') |
||||
|
} |
||||
|
} |
||||
File diff suppressed because it is too large
Loading…
Reference in new issue