This commit is contained in:
X1627315083
2024-01-15 13:20:53 +08:00
parent 3b839bcb44
commit 2fca178eeb
9 changed files with 302 additions and 131 deletions

23
package-lock.json generated
View File

@@ -10,12 +10,14 @@
"dependencies": { "dependencies": {
"@ans1998/vue3-color": "^3.0.7", "@ans1998/vue3-color": "^3.0.7",
"@flaticon/flaticon-uicons": "^2.3.0", "@flaticon/flaticon-uicons": "^2.3.0",
"@types/fingerprintjs2": "^2.0.0",
"ant-design-vue": "^3.2.12", "ant-design-vue": "^3.2.12",
"axios": "^1.4.0", "axios": "^1.4.0",
"core-js": "^3.8.3", "core-js": "^3.8.3",
"driver.js": "^1.3.1", "driver.js": "^1.3.1",
"element-plus": "^2.4.2", "element-plus": "^2.4.2",
"file-saver": "^2.0.5", "file-saver": "^2.0.5",
"fingerprintjs2": "^2.1.4",
"html2canvas": "^1.4.1", "html2canvas": "^1.4.1",
"jszip": "^3.10.1", "jszip": "^3.10.1",
"md5": "^2.3.0", "md5": "^2.3.0",
@@ -2304,6 +2306,11 @@
"@types/range-parser": "*" "@types/range-parser": "*"
} }
}, },
"node_modules/@types/fingerprintjs2": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@types/fingerprintjs2/-/fingerprintjs2-2.0.0.tgz",
"integrity": "sha512-isSTwNnW5I6zGZnpkinmVcV9pJqr7cLELns+tXDYzskIOAb2J+iCQ0mQJ9bRjHJhZfdlTFXZoCYK9ZgT3oMWXQ=="
},
"node_modules/@types/html-minifier-terser": { "node_modules/@types/html-minifier-terser": {
"version": "6.1.0", "version": "6.1.0",
"resolved": "https://registry.npmmirror.com/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", "resolved": "https://registry.npmmirror.com/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz",
@@ -6515,6 +6522,12 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/fingerprintjs2": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/fingerprintjs2/-/fingerprintjs2-2.1.4.tgz",
"integrity": "sha512-veP2yVsnYvjDVkzZMyIEwpqCAQfsBLH+U4PK5MlFAnLjZrttbdRqEArE1fPcnJFz5oS5CrdONbsV7J6FGpIJEQ==",
"deprecated": "Package has been renamed to @fingerprintjs/fingerprintjs. Install @fingerprintjs/fingerprintjs to get updates."
},
"node_modules/flat-cache": { "node_modules/flat-cache": {
"version": "3.0.4", "version": "3.0.4",
"resolved": "https://registry.npmmirror.com/flat-cache/-/flat-cache-3.0.4.tgz", "resolved": "https://registry.npmmirror.com/flat-cache/-/flat-cache-3.0.4.tgz",
@@ -14057,6 +14070,11 @@
"@types/range-parser": "*" "@types/range-parser": "*"
} }
}, },
"@types/fingerprintjs2": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@types/fingerprintjs2/-/fingerprintjs2-2.0.0.tgz",
"integrity": "sha512-isSTwNnW5I6zGZnpkinmVcV9pJqr7cLELns+tXDYzskIOAb2J+iCQ0mQJ9bRjHJhZfdlTFXZoCYK9ZgT3oMWXQ=="
},
"@types/html-minifier-terser": { "@types/html-minifier-terser": {
"version": "6.1.0", "version": "6.1.0",
"resolved": "https://registry.npmmirror.com/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", "resolved": "https://registry.npmmirror.com/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz",
@@ -17428,6 +17446,11 @@
"path-exists": "^4.0.0" "path-exists": "^4.0.0"
} }
}, },
"fingerprintjs2": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/fingerprintjs2/-/fingerprintjs2-2.1.4.tgz",
"integrity": "sha512-veP2yVsnYvjDVkzZMyIEwpqCAQfsBLH+U4PK5MlFAnLjZrttbdRqEArE1fPcnJFz5oS5CrdONbsV7J6FGpIJEQ=="
},
"flat-cache": { "flat-cache": {
"version": "3.0.4", "version": "3.0.4",
"resolved": "https://registry.npmmirror.com/flat-cache/-/flat-cache-3.0.4.tgz", "resolved": "https://registry.npmmirror.com/flat-cache/-/flat-cache-3.0.4.tgz",

View File

@@ -12,12 +12,14 @@
"dependencies": { "dependencies": {
"@ans1998/vue3-color": "^3.0.7", "@ans1998/vue3-color": "^3.0.7",
"@flaticon/flaticon-uicons": "^2.3.0", "@flaticon/flaticon-uicons": "^2.3.0",
"@types/fingerprintjs2": "^2.0.0",
"ant-design-vue": "^3.2.12", "ant-design-vue": "^3.2.12",
"axios": "^1.4.0", "axios": "^1.4.0",
"core-js": "^3.8.3", "core-js": "^3.8.3",
"driver.js": "^1.3.1", "driver.js": "^1.3.1",
"element-plus": "^2.4.2", "element-plus": "^2.4.2",
"file-saver": "^2.0.5", "file-saver": "^2.0.5",
"fingerprintjs2": "^2.1.4",
"html2canvas": "^1.4.1", "html2canvas": "^1.4.1",
"jszip": "^3.10.1", "jszip": "^3.10.1",
"md5": "^2.3.0", "md5": "^2.3.0",

View File

@@ -13,12 +13,23 @@ import VueLazyload from "vue-lazyload";
import i18n from './lang/index' import i18n from './lang/index'
import GO from './tool/GO' import GO from './tool/GO'
import "../node_modules/@flaticon/flaticon-uicons/css/all/all.css" import "../node_modules/@flaticon/flaticon-uicons/css/all/all.css"
import Fingerprint2 from 'fingerprintjs2';//获取浏览器唯一标识
flexible() flexible()
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
// console.log(process.env) // console.log(process.env)
Fingerprint2.get(function(components) {
const values = components.map(function(component,index) {
if (index === 0) { //把微信浏览器里UA的wifi或4G等网络替换成空,不然切换网络会ID不一样
return component.value.replace(/\bNetType\/\w+\b/, '')
}
return component.value
})
// 生成最终id murmur
const murmur = Fingerprint2.x64hash128(values.join(''), 31);
console.log('浏览器指纹码:'+murmur )
})
let loadingParam = { let loadingParam = {
loading: require('./assets/images/homePage/loading.gif'), loading: require('./assets/images/homePage/loading.gif'),
attempt: 1 attempt: 1
} }
createApp(App).use(store).use(router).use(Antd).use(VueLazyload,loadingParam).use(i18n).mount('#app') createApp(App).use(store).use(router).use(Antd).use(VueLazyload,loadingParam).use(i18n).mount('#app')

View File

@@ -44,6 +44,11 @@ const routes: Array<RouteRecordRaw> = [
name: 'trialApproval', name: 'trialApproval',
component: _import('trialApproval') component: _import('trialApproval')
}, },
{
path: '/setIdentification',
name: 'setIdentification',
component: _import('setIdentification')
},
] ]
const router = createRouter({ const router = createRouter({

View File

@@ -1,7 +1,7 @@
const setCookie = (name,value) => { const setCookie = (name,value) => {
var Days = 30; var Days = 30;
var exp = new Date(); var exp = new Date();
exp.setTime(exp.getTime() + Days*24*60*60*30); exp.setTime(exp.getTime() + Days*24*60*60*1000);
document.cookie = name + "="+ escape (value) + ";expires=" + exp.toGMTString(); document.cookie = name + "="+ escape (value) + ";expires=" + exp.toGMTString();
} }

View File

@@ -80,7 +80,7 @@ axios.interceptors.response.use((res) =>{
} }
}, function(error) { }, function(error) {
if(error?.response?.status === 401){ if(error?.response?.status === 401&&router.currentRoute._value.name != 'setIdentification'){//如果是记录浏览器页面就不跳转login
router.replace('/login') router.replace('/login')
return Promise.reject() return Promise.reject()
} }
@@ -89,7 +89,6 @@ axios.interceptors.response.use((res) =>{
return Promise.reject(data_new); return Promise.reject(data_new);
}); });
export const Https = { export const Https = {
httpUrls: { httpUrls: {
interfaceUrl: '', interfaceUrl: '',

View File

@@ -1,170 +1,197 @@
const isEmail = (email)=>{ const isEmail = (email) => {
let reg = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/ let reg = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/
let result = reg.test(email) let result = reg.test(email)
return result return result
}
const getUploadUrl = () => {
let url = process.env.VUE_APP_BASE_URL || ''
// let url = "http://18.167.251.121:10086"
return url
} }
const getUploadUrl = () =>{
let url = process.env.VUE_APP_BASE_URL || ''
// let url = "http://18.167.251.121:10086"
return url
}
function dataURLtoBlob(dataurl) { function dataURLtoBlob(dataurl) {
var arr = dataurl.split(','); var arr = dataurl.split(',');
var mime = arr[0].match(/:(.*?);/)[1]; var mime = arr[0].match(/:(.*?);/)[1];
var bstr =atob(arr[1]); var bstr = atob(arr[1]);
var n = bstr.length; var n = bstr.length;
var u8arr =new Uint8Array(n); var u8arr = new Uint8Array(n);
while (n--) { while (n--) {
u8arr[n] = bstr.charCodeAt(n); u8arr[n] = bstr.charCodeAt(n);
} }
return new Blob([u8arr], {type: mime }); return new Blob([u8arr], { type: mime });
} }
function blobToFile(blob, fileName){ function blobToFile(blob, fileName) {
blob.lastModifiedDate =new Date(); blob.lastModifiedDate = new Date();
blob.name = fileName; blob.name = fileName;
return blob; return blob;
} }
//下载图片 //下载图片
function downloadIamge (imgsrc, name) { // 下载图片地址和图片名 function downloadIamge(imgsrc, name) { // 下载图片地址和图片名
var image = new Image() var image = new Image()
// 解决跨域 Canvas 污染问题 // 解决跨域 Canvas 污染问题
image.setAttribute('crossOrigin', 'anonymous') image.setAttribute('crossOrigin', 'anonymous')
image.onload = function () { image.onload = function () {
var canvas = document.createElement('canvas') var canvas = document.createElement('canvas')
canvas.width = image.width canvas.width = image.width
canvas.height = image.height canvas.height = image.height
var context = canvas.getContext('2d') var context = canvas.getContext('2d')
context.drawImage(image, 0, 0, image.width, image.height) context.drawImage(image, 0, 0, image.width, image.height)
var url = canvas.toDataURL('image/jpeg') // 得到图片的base64编码数据 var url = canvas.toDataURL('image/jpeg') // 得到图片的base64编码数据
var a = document.createElement('a') // 生成一个a元素 var a = document.createElement('a') // 生成一个a元素
var event = new MouseEvent('click') // 创建一个单击事件 var event = new MouseEvent('click') // 创建一个单击事件
a.download = name || 'generate' // 设置图片名称 a.download = name || 'generate' // 设置图片名称
a.href = url // 将生成的URL设置为a.href属性 a.href = url // 将生成的URL设置为a.href属性
a.target='_blank' a.target = '_blank'
a.dispatchEvent(event) // 触发a的单击事件 a.dispatchEvent(event) // 触发a的单击事件
} }
image.src = imgsrc image.src = imgsrc
} }
function dataURLtoFile(dataurl, filename){ function dataURLtoFile(dataurl, filename) {
var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1], var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n); bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
while(n--){ while (n--) {
u8arr[n] = bstr.charCodeAt(n); u8arr[n] = bstr.charCodeAt(n);
} }
var blob = dataURLtoBlob(dataurl); var blob = dataURLtoBlob(dataurl);
return blobToFile(blob, filename); return blobToFile(blob, filename);
} }
const base64toFile = (dataurl, filename = 'file') => { const base64toFile = (dataurl, filename = 'file') => {
let arr = dataurl.split(',') let arr = dataurl.split(',')
let mime = arr[0].match(/:(.*?);/)[1] let mime = arr[0].match(/:(.*?);/)[1]
let suffix = mime.split('/')[1] let suffix = mime.split('/')[1]
let bstr = atob(arr[1]) let bstr = atob(arr[1])
let n = bstr.length let n = bstr.length
let u8arr = new Uint8Array(n) let u8arr = new Uint8Array(n)
while (n--) { while (n--) {
u8arr[n] = bstr.charCodeAt(n) u8arr[n] = bstr.charCodeAt(n)
} }
return new File([u8arr], `${filename}.${suffix}`, { return new File([u8arr], `${filename}.${suffix}`, {
type: mime type: mime
}) })
} }
function rgbToHsv([R, G, B]) { function rgbToHsv([R, G, B]) {
R /= 255 R /= 255
G /= 255 G /= 255
B /= 255 B /= 255
const max = Math.max(R, G, B) const max = Math.max(R, G, B)
const min = Math.min(R, G, B) const min = Math.min(R, G, B)
const delta = max - min const delta = max - min
var H,S,V var H, S, V
if (delta === 0) { if (delta === 0) {
H = 0; H = 0;
} else if (max === R) { } else if (max === R) {
H = ((G - B) / delta) % 6; H = ((G - B) / delta) % 6;
} else if (max === G) { } else if (max === G) {
H = (B - R) / delta + 2; H = (B - R) / delta + 2;
} else { // max === B } else { // max === B
H = (R - G) / delta + 4; H = (R - G) / delta + 4;
} }
H = Math.round(H * 60); // 范围为 0-360 H = Math.round(H * 60); // 范围为 0-360
if(H<0){ if (H < 0) {
H = 360+H H = 360 + H
} }
if (max === 0) { if (max === 0) {
S = 0; S = 0;
} else { } else {
S = delta / max; S = delta / max;
} }
S = Math.round(S*100); // 范围为 0-100 S = Math.round(S * 100); // 范围为 0-100
V = Math.round(max*100); // 范围为 0-100 V = Math.round(max * 100); // 范围为 0-100
return [H, S, V] return [H, S, V]
} }
const formatTime = (timestamp, fmt) =>{ const formatTime = (timestamp, fmt) => {
// date = new Date(), fmt = 'MM/dd/yyyy'; // date = new Date(), fmt = 'MM/dd/yyyy';
let date = new Date(); let date = new Date();
date.setTime(timestamp * 1000); date.setTime(timestamp * 1000);
if (!fmt) { if (!fmt) {
formatRule ? (fmt = formatRule) : (fmt = "YYYY-MM-DD hh:mm:ss"); formatRule ? (fmt = formatRule) : (fmt = "YYYY-MM-DD hh:mm:ss");
} }
// console.log(formatRule) // console.log(formatRule)
let o = { let o = {
'M+': date.getMonth() + 1, // 月份 'M+': date.getMonth() + 1, // 月份
'D+': date.getDate(), // 日 'D+': date.getDate(), // 日
'h+': date.getHours(), // 小时 'h+': date.getHours(), // 小时
'm+': date.getMinutes(), // 分 'm+': date.getMinutes(), // 分
's+': date.getSeconds(), // 秒 's+': date.getSeconds(), // 秒
'q+': Math.floor((date.getMonth() + 3) / 3), // 季度 'q+': Math.floor((date.getMonth() + 3) / 3), // 季度
'S+': date.getMilliseconds(), // 毫秒 'S+': date.getMilliseconds(), // 毫秒
'a': date.getHours() > 12 'a': date.getHours() > 12
? 'PM' ? 'PM'
: 'AM' // 上午还是下午 : 'AM' // 上午还是下午
}; };
if (/(Y+)/.test(fmt)) { if (/(Y+)/.test(fmt)) {
fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length)); fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length));
} }
if(/(a)/.test(fmt)&&o['h+']>12){ if (/(a)/.test(fmt) && o['h+'] > 12) {
o['h+'] = o['h+'] - 12 o['h+'] = o['h+'] - 12
} }
for (let k in o) { for (let k in o) {
if (new RegExp('(' + k + ')').test(fmt)) { if (new RegExp('(' + k + ')').test(fmt)) {
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1)
? (o[k]) ? (o[k])
: (('00' + o[k]).substr(('' + o[k]).length))); : (('00' + o[k]).substr(('' + o[k]).length)));
} }
} }
return fmt; return fmt;
} }
const isMoible = () => { const isMoible = () => {
let is_mobile = navigator.userAgent.toLowerCase().match(/(ipad|ipod|iphone|android|coolpad|mmp|smartphone|midp|wap|xoom|symbian|j2me|blackberry|wince)/i) != null; let is_mobile = navigator.userAgent.toLowerCase().match(/(ipad|ipod|iphone|android|coolpad|mmp|smartphone|midp|wap|xoom|symbian|j2me|blackberry|wince)/i) != null;
if(is_mobile){ if (is_mobile) {
return true return true
}else{ } else {
return false return false
} }
} }
function getBrowserInfo() {//获取是什么浏览器
export{ var agent = navigator.userAgent.toLowerCase();
isEmail, var userAgent = navigator.userAgent;
getUploadUrl, var regStr_ie = /msie [\d.]+;/gi;
dataURLtoFile, var regStr_ff = /firefox\/[\d.]+/gi
blobToFile, var regStr_chrome = /chrome\/[\d.]+/gi;
base64toFile, var regStr_saf = /safari\/[\d.]+/gi;
rgbToHsv, var isIE = userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1; //判断是否IE<11浏览器
formatTime, var isEdge = userAgent.indexOf("Edge") > -1 && !isIE; //判断是否IE的Edge浏览器
dataURLtoBlob, console.log(isIE,isEdge);
isMoible, //IE
if (agent.indexOf("msie") > 0) {
return agent.match(regStr_ie);
}
//firefox
if (agent.indexOf("firefox") > 0) {
return agent.match(regStr_ff);
}
//Chrome
if (agent.indexOf("chrome") > 0) {
return agent.match(regStr_chrome);
}
//Safari
if (agent.indexOf("safari") > 0 && agent.indexOf("chrome") < 0) {
return agent.match(regStr_saf);
}
}
export {
isEmail,
getUploadUrl,
dataURLtoFile,
blobToFile,
base64toFile,
rgbToHsv,
formatTime,
dataURLtoBlob,
isMoible,
downloadIamge, downloadIamge,
getBrowserInfo,
} }

View File

@@ -463,6 +463,8 @@ export default defineComponent({
Https.axiosPost(Https.httpUrls.accountLogin, data).then( Https.axiosPost(Https.httpUrls.accountLogin, data).then(
(rv: any) => { (rv: any) => {
if (rv) { if (rv) {
console.log(rv);
this.createTimer(); this.createTimer();
let isTest = rv.isTrial == 1?true:false let isTest = rv.isTrial == 1?true:false
let isBeginner = rv.isBeginner == 1?true:false let isBeginner = rv.isBeginner == 1?true:false

View File

@@ -0,0 +1,102 @@
<template>
<div class="identification_page">
<div>密钥<input type="text" autofocus /></div>
<div class="button" @click="getFingerprint2">记录浏览器</div>
</div>
</template>
<script lang="ts">
import { defineComponent, ref, createVNode, computed } from "vue";
import { setCookie, getCookie, WriteCookie } from "@/tool/cookie";
import HeaderComponent from "@/component/HomePage/Header.vue";
import HistoryDetail from "@/component/Detail/HistoryDetail.vue";
import router from "@/router/index";
import { Https } from "@/tool/https";
import { formatTime, getBrowserInfo } from "@/tool/util";
import { Modal, message } from "ant-design-vue";
import RobotAssist from "@/component/HomePage/RobotAssist.vue";
import { ExclamationCircleOutlined } from "@ant-design/icons-vue";
import { useI18n } from "vue-i18n";
import Fingerprint2 from "fingerprintjs2"; //获取浏览器唯一标识
export default defineComponent({
components: {
HeaderComponent,
HistoryDetail,
RobotAssist,
},
setup() {
let collectionList: any = ref([]);
let userInfo: any = {};
let status: any = ref(0);
let voluntarily: any = ref(false);
return {
collectionList,
userInfo,
status,
voluntarily,
};
},
data() {
return {};
},
mounted() {
// this.userInfo = JSON.parse(getCookie("userInfo") as any);
// if (this.userInfo.userId == 83) {
// } else {
// router.replace("/home");
// return
// }
},
methods: {
async getFingerprint2() {
let murmur:any = ''
await new Promise((resolve,reject)=>{
Fingerprint2.get(function (components: any) {
const values = components.map(function (
component: any,
index: any
) {
if (index === 0) {
//把微信浏览器里UA的wifi或4G等网络替换成空,不然切换网络会ID不一样
return component.value.replace(/\bNetType\/\w+\b/, "");
}
return component.value;
});
// 生成最终id murmur
murmur = Fingerprint2.x64hash128(values.join(""), 31);
console.log("浏览器指纹码:" + murmur);
resolve('')
});
})
let data = {}
console.log(11);
// Https.axiosPost(Https.httpUrls.designSingle, data)
// .then((rv) => {
// // designItemDetail.clothes[index].printObject.path = rv.clothes[0].printObject.path
// })
// .catch((res) => {
// });
},
},
});
</script>
<style lang="less">
.identification_page {
margin-top: 200px;
display: flex;
flex-direction: column;
align-items: center;
input {
padding-left: 10px;
border: 2px solid rgba(0, 0, 0, 0.2);
border-radius: 10px;
}
.button {
margin-top: 20px;
border: 2px solid;
border-radius: 20px;
padding: 0 20px;
cursor: pointer;
}
}
</style>