@@ -2,6 +2,18 @@ | |||
<router-view></router-view> | |||
</template> | |||
<!-- | |||
setup() :开始创建组件之前,在beforeCreate和created之前执行。创建的是data和method | |||
onBeforeMount() : 组件挂载到节点上之前执行的函数。 | |||
onMounted() : 组件挂载完成后执行的函数。 | |||
onBeforeUpdate(): 组件更新之前执行的函数。 | |||
onUpdated(): 组件更新完成之后执行的函数。 | |||
onBeforeUnmount(): 组件卸载之前执行的函数。 | |||
onUnmounted(): 组件卸载完成后执行的函数 | |||
若组件被包含,则多出下面两个钩子函数。 | |||
onActivated(): 被包含在中的组件,会多出两个生命周期钩子函数。被激活时执行 。 | |||
onDeactivated(): 比如从 A组件,切换到 B 组件,A 组件消失时执行。 | |||
--> | |||
<script lang="ts"> | |||
import { defineComponent } from 'vue' | |||
@@ -20,11 +32,13 @@ body { | |||
padding: 0; | |||
margin: 0; | |||
} | |||
#app { | |||
width: 100%; | |||
height: 100%; | |||
font-family: 'Microsoft Yahei', Arial, sans-serif; | |||
} | |||
#app .content-warpper { | |||
padding: 0 22px 20px; | |||
/* background: #f8f8f8; */ |
@@ -1,6 +1,8 @@ | |||
<template> | |||
<div class="as-gravity-center as-radius-5px" @mouseup="onmouseup" style="background-color:#FFFFFF; | |||
padding: 15px 10px 15px 10px;width:340px;box-shadow: 0px 0px 5px #999999;"> | |||
<!-- <img src="http://localhost:2222/slide_img_four.jpg" style="height: 200px;width: 300px;"> | |||
<img src="http://localhost:2222/slide_img_three.jpg" style="height: 200px;width: 300px;"> --> | |||
<div :style="`width: ${totalWidth}px;`"> | |||
<!-- 文字提示 --> | |||
<div class="as-gravity-center-start" style="display:flex;margin-bottom: 10px;"> | |||
@@ -23,7 +25,7 @@ | |||
<!-- 图片层 --> | |||
<div style="max-height: 200px;margin-bottom: 10px;"> | |||
<!-- 图片 --> | |||
<img :src="SlideImgThreePng" class="as-radius-5px" style="height: 200px;width: 300px;"> | |||
<img :src="bgImg" class="as-radius-5px" style="height: 200px;width: 300px;"> | |||
<!-- 裁剪部分 background-color: #3FC0FC; --> | |||
<canvas class="as-radius-5px" id="canvas-cut" :width="canWidth * 2" :height="canHeight * 2" | |||
style="position: relative;z-index: 10;top: 0px;box-shadow: 1px 1px 2.5px #333;" | |||
@@ -62,93 +64,111 @@ | |||
</template> | |||
<script> | |||
import SlideImgThreePng from '@/assets/image/slide_img_three.png'; | |||
//md开撸第二版 | |||
export default { | |||
props: { | |||
marginTop: { //高度 | |||
default: 40, | |||
type: Number | |||
}, | |||
marginLeft: { //宽度 | |||
default: 80, | |||
type: Number | |||
}, | |||
figure: { //灵敏度 | |||
default: 10, | |||
type: Number | |||
} | |||
import SlideImgThreePng from '@/assets/image/slide_img_three.png'; | |||
//md开撸第二版 | |||
export default { | |||
props: { | |||
marginTop: { //高度 | |||
default: 60, | |||
type: Number | |||
}, | |||
data() { | |||
return { | |||
totalWidth: 300, //设置总宽 | |||
dragWidth: 45, //拖动圆大小 | |||
dragBgWidth: 0, //拖动背景 | |||
slidingX: 0, //圆位置 | |||
slidingBg: undefined, | |||
clickStart: false, //点击状态 | |||
bgColor: '#3FC0FC', //#FF5B57 | |||
succeed: false, //展示状态 | |||
canWidth: 60, //60 | |||
canHeight: 40, //40 | |||
initTop: -205, | |||
initLeft: -60, | |||
canLeft: 0, | |||
SlideImgThreePng | |||
} | |||
marginLeft: { //宽度 | |||
default: 120, | |||
type: Number | |||
}, | |||
mounted() { | |||
const { | |||
marginTop, | |||
marginLeft, | |||
canWidth, | |||
canHeight | |||
} = this | |||
//设置阴影位置 | |||
this.initTop = this.initTop + this.marginTop | |||
this.initLeft = this.initLeft + this.marginLeft | |||
// 获取滑块背景位置 | |||
this.slidingBg = this.$refs['slidingBg'].getBoundingClientRect() | |||
//裁剪视图 | |||
let canvas = document.getElementById('canvas-cut'); | |||
let cut = canvas.getContext('2d'); | |||
let img = new Image(); | |||
img.src = this.SlideImgThreePng; | |||
//处理toDataURL遇跨域资源导致的报错 | |||
img.crossOrigin = 'Anonymous'; | |||
img.onload = function () { | |||
/* | |||
drawImage方法说明 https://www.runoob.com/jsref/met-canvas-drawimage.html | |||
sx 可选。开始剪切的 x 坐标位置。 | |||
sy 可选。开始剪切的 y 坐标位置。 | |||
swidth 可选。被剪切图像的宽度。 | |||
sheight 可选。被剪切图像的高度。 | |||
x 在画布上放置图像的 x 坐标位置。 | |||
y 在画布上放置图像的 y 坐标位置。 | |||
width 可选。要使用的图像的宽度(伸展或缩小图像)。 | |||
height 可选。要使用的图像的高度(伸展或缩小图像)。 | |||
//在画布上定位图像: | |||
drawImage(image, dx, dy) | |||
//在画布上定位图像,并规定图像的宽度和高度: | |||
drawImage(image, dx, dy, dw, dh) | |||
//剪切图像,并在画布上定位被剪切的部分: | |||
context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height); | |||
*/ | |||
console.log(canWidth * 4, canHeight * 4); | |||
cut.drawImage(img, marginLeft * 5.4, marginTop * 5.4, 600, 400, 0, 0, canWidth * 4, canHeight * | |||
4); //通过缩放增加截取图片的清晰度 | |||
}; | |||
figure: { //灵敏度 | |||
default: 10, | |||
type: Number | |||
}, | |||
width: {}, | |||
methods: { | |||
close() { //关闭监听 | |||
this.$emit('close'); | |||
}, | |||
onmousedown(event) { //鼠标按下事件 | |||
this.init(0) | |||
this.clickStart = true | |||
}, | |||
onmouseup(event) { //鼠标抬起 | |||
bgImg: { //图片背景 | |||
default: SlideImgThreePng, | |||
type: String | |||
} | |||
}, | |||
data() { | |||
return { | |||
totalWidth: 300, //设置总宽 | |||
dragWidth: 45, //拖动圆大小 | |||
dragBgWidth: 0, //拖动背景 | |||
slidingX: 0, //圆位置 | |||
slidingBg: undefined, | |||
clickStart: false, //点击状态 | |||
bgColor: '#3FC0FC', //#FF5B57 | |||
succeed: false, //展示状态 | |||
canWidth: 60, //60 | |||
canHeight: 40, //40 | |||
initTop: -205, | |||
initLeft: -60, | |||
canLeft: 0, | |||
SlideImgThreePng | |||
} | |||
}, | |||
create() { | |||
}, | |||
mounted() { | |||
const { | |||
marginTop, | |||
marginLeft, | |||
canWidth, | |||
canHeight | |||
} = this | |||
//设置阴影位置 | |||
this.initTop = this.initTop + this.marginTop | |||
this.initLeft = this.initLeft + this.marginLeft | |||
// 获取滑块背景位置 | |||
this.slidingBg = this.$refs['slidingBg'].getBoundingClientRect() | |||
//裁剪视图 | |||
let canvas = document.getElementById('canvas-cut'); | |||
let cut = canvas.getContext('2d'); | |||
let img = new Image(); | |||
img.src = this.bgImg; | |||
//处理toDataURL遇跨域资源导致的报错 | |||
img.crossOrigin = 'Anonymous'; | |||
//设置固定宽高 | |||
// img.height = 200; | |||
// img.width = 300; | |||
img.onload = function () { | |||
/* | |||
drawImage方法说明 https://www.runoob.com/jsref/met-canvas-drawimage.html | |||
sx 可选。开始剪切的 x 坐标位置。 | |||
sy 可选。开始剪切的 y 坐标位置。 | |||
swidth 可选。被剪切图像的宽度。 | |||
sheight 可选。被剪切图像的高度。 | |||
x 在画布上放置图像的 x 坐标位置。 | |||
y 在画布上放置图像的 y 坐标位置。 | |||
width 可选。要使用的图像的宽度(伸展或缩小图像)。 | |||
height 可选。要使用的图像的高度(伸展或缩小图像)。 | |||
//在画布上定位图像: | |||
drawImage(image, dx, dy) | |||
//在画布上定位图像,并规定图像的宽度和高度: | |||
drawImage(image, dx, dy, dw, dh) | |||
//剪切图像,并在画布上定位被剪切的部分: | |||
context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height); | |||
*/ | |||
//通过缩放增加截取图片的清晰度 1427 x 933 6000 x 4000 | |||
cut.drawImage(img, | |||
marginLeft * (4.5 * (img.width / 1390).toFixed(2)), | |||
marginTop * (4.5 * (img.height / 930).toFixed(2)), | |||
600 * (img.width / 1400).toFixed(2), | |||
400 * (img.height / 930).toFixed(2), | |||
0, 0, canWidth * 4, canHeight * 4); | |||
}; | |||
}, | |||
width: {}, | |||
methods: { | |||
close() { //关闭监听 | |||
this.$emit('close'); | |||
}, | |||
refresh() { | |||
this.$emit('refresh'); | |||
}, | |||
onmousedown(event) { //鼠标按下事件 | |||
this.init(0) | |||
this.clickStart = true | |||
}, | |||
onmouseup(event) { //鼠标抬起 | |||
this.$nextTick(() => { | |||
this.clickStart = false | |||
if (this.marginLeft + this.figure > this.canLeft && this.canLeft > this.marginLeft - 5) { | |||
this.succeed = true | |||
@@ -165,68 +185,72 @@ | |||
this.$emit('fail') | |||
}, 1000) | |||
} | |||
}, | |||
onmousemove(event) { //鼠标移动事件 | |||
if (this.clickStart) { | |||
const { | |||
slidingBg, | |||
dragWidth, | |||
totalWidth | |||
} = this | |||
const value = event.x - (slidingBg.x + dragWidth / 2) //移动的值 | |||
//限制移动范围 | |||
if (value > 0 && value < totalWidth - dragWidth) { | |||
this.init(value) | |||
} | |||
}) | |||
}, | |||
onmousemove(event) { //鼠标移动事件 | |||
if (this.clickStart) { | |||
const { | |||
slidingBg, | |||
dragWidth, | |||
totalWidth | |||
} = this | |||
const value = event.x - (slidingBg.x + dragWidth / 2) //移动的值 | |||
//限制移动范围 | |||
if (value > 0 && value < totalWidth - dragWidth) { | |||
this.init(value) | |||
} | |||
}, | |||
init(value) { | |||
} | |||
}, | |||
init(value) { | |||
//处理滑块超出问题 | |||
this.$nextTick(() => { | |||
this.slidingX = value | |||
this.dragBgWidth = value + this.dragWidth / 2 | |||
//处理滑块超出问题 | |||
if (value > (this.totalWidth - this.dragWidth) / 2) { | |||
//判断滑动位置 | |||
if (value > (this.totalWidth - this.dragWidth) - 30) { | |||
this.canLeft = value - 15 | |||
} else { | |||
this.canLeft = value | |||
} | |||
} | |||
}) | |||
} | |||
} | |||
} | |||
</script> | |||
<style lang="scss" scoped> | |||
.slide-bg { | |||
color: #3FC0FC; | |||
height: 45px; | |||
background-color: #DBF1FF; | |||
} | |||
.slide-bg { | |||
color: #3FC0FC; | |||
height: 45px; | |||
background-color: #DBF1FF; | |||
} | |||
.slide-bg-tier { | |||
height: 45px; | |||
position: relative; | |||
z-index: 10; | |||
border-radius: 30px 0 0 30px; | |||
top: -45px | |||
} | |||
.slide-bg-tier { | |||
height: 45px; | |||
position: relative; | |||
z-index: 10; | |||
border-radius: 30px 0 0 30px; | |||
top: -45px | |||
} | |||
.slide-reight { | |||
position: relative; | |||
height: 45px; | |||
width: 100%; | |||
top: -90px; | |||
} | |||
.slide-reight { | |||
position: relative; | |||
height: 45px; | |||
width: 100%; | |||
top: -90px; | |||
} | |||
.circle-bg { | |||
height: 45px; | |||
background-color: #fff; | |||
position: relative; | |||
border-radius: 100px; | |||
z-index: 10; | |||
} | |||
.circle-bg { | |||
height: 45px; | |||
background-color: #fff; | |||
position: relative; | |||
border-radius: 100px; | |||
z-index: 10; | |||
} | |||
.circle-bg-text { | |||
height: 100%; | |||
font-size: 24px; | |||
color: #3FC0FC; | |||
user-select: none | |||
} | |||
.circle-bg-text { | |||
height: 100%; | |||
font-size: 24px; | |||
color: #3FC0FC; | |||
user-select: none | |||
} | |||
</style> |
@@ -45,7 +45,7 @@ export const defaultOptions: {} = { | |||
crudShow: true, //是否显示CURD操作栏 (默认true) | |||
crudChildShow: true, //是否显示CURD子操作栏 (默认true) | |||
crud: { | |||
add: true, | |||
add: true, | |||
edit: false, | |||
delete: false, | |||
derive: false, |
@@ -118,19 +118,7 @@ const props = defineProps({ | |||
//表单数据 | |||
type: Array, | |||
default: function () { | |||
return [ | |||
{ | |||
one: '范晓东', | |||
two: '贵ZEY123', | |||
three: '蓝色', | |||
four: '52011328220201499572', | |||
five: '正常', | |||
six: '储值卡', | |||
seven: '52011328220201499572', | |||
eight: '正常', | |||
data: '2020-12-24', | |||
} | |||
] | |||
return [] | |||
}, | |||
}, | |||
}) |
@@ -16,8 +16,6 @@ | |||
<!-- 子项也负责跳转 --> | |||
<router-link style="text-decoration: none" v-else :to="{ name: `${item.path}` }"> | |||
<el-menu-item class="el-menu-item" :index="item.title + ',' + item.path"> | |||
<item-ioc v-if="item.icon" :icon="item.icon" /> | |||
<template #title> | |||
<span style="font-size: 14px">{{ item.title }}</span> |
@@ -1,6 +1,7 @@ | |||
import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router' | |||
import Cookies from 'js-cookie' | |||
// component: () => import('') 异步加载 | |||
const routes: RouteRecordRaw[] = [ | |||
{ | |||
path: '/', |
@@ -2,7 +2,10 @@ | |||
<video-bg :sources="[bgVideo]"> | |||
<div v-if="verify" class="as-gravity-center" | |||
style="z-index: 10; position: absolute; left: 0; top: 0;right: 0px;bottom: 0px;margin: auto;"> | |||
<sliding-block-verify-two @succeed="succeed" @fail="fail" @close="close"></sliding-block-verify-two> | |||
<sliding-block-verify-two :marginTop="slidingBlock.marginTop" :marginLeft="slidingBlock.marginLeft" | |||
:bgImg="slidingBlock.bgImg" @succeed="succeed" @fail="fail" @close="close" @refresh="refresh"> | |||
</sliding-block-verify-two> | |||
</div> | |||
<div class="login"> | |||
@@ -29,155 +32,183 @@ | |||
</template> | |||
<script setup lang="ts"> | |||
import { | |||
reactive, | |||
ref | |||
} from 'vue' | |||
import { | |||
useRoute, | |||
useRouter | |||
} from 'vue-router' | |||
import { | |||
ElNotification | |||
} from 'element-plus' | |||
import bgTwo from '@/assets/video/homeBg.mp4' | |||
import VideoBg from '@/components/VideoBackround/VideoBackground.vue' | |||
import { | |||
User, | |||
Lock | |||
} from '@element-plus/icons-vue' | |||
import Cookies from 'js-cookie' | |||
//引入滑块组件 | |||
import SlidingBlockVerifyTwo from '@/components/SlidingBlockVerifyTwo/SlidingBlockVerifyTwo.vue' | |||
const form = ref() | |||
const router = useRouter() | |||
const bgVideo = bgTwo | |||
const verify = ref(false) | |||
console.log(bgVideo); | |||
const item = reactive<any>({ | |||
account: 'admin', | |||
password: '123456', | |||
rememberPSWD: '' | |||
}) | |||
//记住密码处理(自动登录) | |||
if (Cookies.get('rememberPSWD')) { | |||
item.account = Cookies.get('account') | |||
item.password = Cookies.get('password') | |||
router.replace({ | |||
name: 'Layout' | |||
import { | |||
reactive, | |||
ref, | |||
getCurrentInstance, | |||
nextTick | |||
} from 'vue' | |||
import { | |||
useRoute, | |||
useRouter | |||
} from 'vue-router' | |||
import { | |||
ElNotification | |||
} from 'element-plus' | |||
import bgTwo from '@/assets/video/homeBg.mp4' | |||
import VideoBg from '@/components/VideoBackround/VideoBackground.vue' | |||
import { | |||
User, | |||
Lock | |||
} from '@element-plus/icons-vue' | |||
import Cookies from 'js-cookie' | |||
import SlideImgThreePng from '@/assets/image/slide_img_three.png'; | |||
//@ts-ignore 引入滑块组件 | |||
import SlidingBlockVerifyTwo from '@/components/SlidingBlockVerifyTwo/SlidingBlockVerifyTwo.vue' | |||
const form = ref() | |||
const router = useRouter() | |||
const bgVideo = bgTwo | |||
const verify = ref(false) | |||
const { | |||
proxy | |||
}: any = getCurrentInstance(); | |||
const slidingBlock = reactive({ | |||
marginTop: 100, //10-150 | |||
marginLeft: 100, //80-220 | |||
bgImg: "http://localhost:2222/滑块/one.jpg" | |||
// bgImg: "http://localhost:2222/slide_img_three.jpg" | |||
// bgImg: "http://localhost:2222/slide_img_four.jpg" | |||
}) | |||
const refresh = () => { | |||
proxy.$request.post('initialValue', {}, { | |||
baseURL: 'http://localhost:8081/' | |||
}).then((res: any) => { | |||
console.log(res.data); | |||
slidingBlock.marginTop = res.data.coordinateX | |||
slidingBlock.marginLeft = res.data.coordinateY | |||
slidingBlock.bgImg = res.data.background | |||
verify.value = false | |||
nextTick(() => { | |||
verify.value = true | |||
}) | |||
} | |||
const rules = reactive({ | |||
account: [{ | |||
required: true, | |||
message: '账号不能为空', | |||
trigger: 'blur', | |||
}], | |||
password: [{ | |||
required: true, | |||
message: '密码不能为空', | |||
trigger: 'blur', | |||
}], | |||
rememberPSWD: [{ | |||
trigger: 'blur', | |||
}] | |||
}).catch((err: any) => { | |||
console.log(err, '====456'); | |||
}) | |||
//请求成功 | |||
const succeed = (() => { | |||
verify.value = false | |||
if (item.account !== 'admin' && item.password !== '123456') { | |||
ElNotification({ | |||
title: '提示', | |||
message: '用户名密码错误', | |||
type: 'error', | |||
}) | |||
return | |||
} | |||
Cookies.set('token', 'demo') | |||
} | |||
const item = reactive<any>({ | |||
account: 'admin', | |||
password: '123456', | |||
rememberPSWD: '' | |||
}) | |||
//记住密码处理(自动登录) | |||
if (Cookies.get('rememberPSWD')) { | |||
item.account = Cookies.get('account') | |||
item.password = Cookies.get('password') | |||
router.replace({ | |||
name: 'Layout' | |||
}) | |||
} | |||
const rules = reactive({ | |||
account: [{ | |||
required: true, | |||
message: '账号不能为空', | |||
trigger: 'blur', | |||
}], | |||
password: [{ | |||
required: true, | |||
message: '密码不能为空', | |||
trigger: 'blur', | |||
}], | |||
rememberPSWD: [{ | |||
trigger: 'blur', | |||
}] | |||
}) | |||
//请求成功 | |||
const succeed = (() => { | |||
verify.value = false | |||
if (item.account !== 'admin' && item.password !== '123456') { | |||
ElNotification({ | |||
title: '提示', | |||
message: '登录成功!', | |||
type: 'success', | |||
}) | |||
router.replace({ | |||
name: 'Layout' | |||
message: '用户名密码错误', | |||
type: 'error', | |||
}) | |||
return | |||
} | |||
Cookies.set('token', 'demo') | |||
ElNotification({ | |||
title: '提示', | |||
message: '登录成功!', | |||
type: 'success', | |||
}) | |||
router.replace({ | |||
name: 'Layout' | |||
}) | |||
}) | |||
//验证失败 | |||
const fail = (() => { | |||
//验证失败 | |||
const fail = (() => { | |||
}) | |||
}) | |||
//关闭 | |||
const close = (() => { | |||
verify.value = false | |||
}) | |||
//关闭 | |||
const close = (() => { | |||
verify.value = false | |||
}) | |||
const submitForm = (formEl: any) => { | |||
if (!formEl) { | |||
return | |||
} | |||
formEl.validate((valid: any) => { | |||
if (valid) { //是否通过表单验证 | |||
if (item.rememberPSWD) { | |||
Cookies.set('account', item.account) | |||
Cookies.set('password', item.password) | |||
Cookies.set('rememberPSWD', item.rememberPSWD) | |||
} else { // 清楚Cookies | |||
Cookies.remove('account') | |||
Cookies.remove('password') | |||
Cookies.remove('rememberPSWD') | |||
} | |||
//获取验证码参数 | |||
verify.value = true | |||
} else { | |||
return false | |||
} | |||
}) | |||
const submitForm = (formEl: any) => { | |||
if (!formEl) { | |||
return | |||
} | |||
formEl.validate((valid: any) => { | |||
if (valid) { //是否通过表单验证 | |||
if (item.rememberPSWD) { | |||
Cookies.set('account', item.account) | |||
Cookies.set('password', item.password) | |||
Cookies.set('rememberPSWD', item.rememberPSWD) | |||
} else { // 清楚Cookies | |||
Cookies.remove('account') | |||
Cookies.remove('password') | |||
Cookies.remove('rememberPSWD') | |||
} | |||
//获取验证码参数 | |||
verify.value = true | |||
} else { | |||
return false | |||
} | |||
}) | |||
} | |||
</script> | |||
<style lang="scss" scoped> | |||
.login { | |||
display: flex; | |||
justify-content: center; | |||
align-items: center; | |||
height: 100%; | |||
background-size: cover; | |||
opacity: 0.8; | |||
} | |||
.title { | |||
margin: 0 auto 30px auto; | |||
text-align: center; | |||
color: #707070; | |||
} | |||
.login-form { | |||
border-radius: 6px; | |||
background: #ffffff; | |||
width: 385px; | |||
padding: 25px 25px 5px 25px; | |||
.el-input { | |||
.login { | |||
display: flex; | |||
justify-content: center; | |||
align-items: center; | |||
height: 100%; | |||
background-size: cover; | |||
opacity: 0.8; | |||
} | |||
.title { | |||
margin: 0 auto 30px auto; | |||
text-align: center; | |||
color: #707070; | |||
} | |||
.login-form { | |||
border-radius: 6px; | |||
background: #ffffff; | |||
width: 385px; | |||
padding: 25px 25px 5px 25px; | |||
.el-input { | |||
height: 38px; | |||
input { | |||
height: 38px; | |||
input { | |||
height: 38px; | |||
} | |||
} | |||
} | |||
.input-icon { | |||
height: 39px; | |||
width: 14px; | |||
margin-left: 2px; | |||
} | |||
.input-icon { | |||
height: 39px; | |||
width: 14px; | |||
margin-left: 2px; | |||
} | |||
} | |||
</style> |