抽奖
This commit is contained in:
26
src/pages/index/activity.vue
Normal file
26
src/pages/index/activity.vue
Normal file
@@ -0,0 +1,26 @@
|
||||
<template>
|
||||
<view>
|
||||
<GGL></GGL>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import GGL from './components/ggl/index'
|
||||
export default {
|
||||
components: {
|
||||
GGL
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
147
src/pages/index/components/ggl/index.vue
Normal file
147
src/pages/index/components/ggl/index.vue
Normal file
@@ -0,0 +1,147 @@
|
||||
<template>
|
||||
<view style="padding-bottom: 50px;background-color: #9e0f00;">
|
||||
<image class="wp100" mode="widthFix" src="https://jwl-jiakao-bq.oss-cn-hangzhou.aliyuncs.com/%E5%B0%8F%E7%A8%8B%E5%BA%8F/%E5%9B%BE%E7%89%87/ggl_header.png"></image>
|
||||
<view class="tip">您今日还剩1次刮奖机会,共有999人参加活动</view>
|
||||
<view class="scraping">
|
||||
<scraping-card :result="result" watermark="刮一刮" title="刮一刮赢取大奖" ref="reset" ></scraping-card>
|
||||
<view v-if="showBtn" class="gj">
|
||||
<view class="btn" @tap="handleScrap">
|
||||
点我刮奖
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="relative mt30 m20lr">
|
||||
<image class="wp100" mode="widthFix" src="/static/image/index/tip.png"></image>
|
||||
<view class="title">中奖名单</view>
|
||||
<view class="card">
|
||||
<view v-for="(item, index) in winningList" :key="index" class="card-item">
|
||||
<text class="item-text">188****8888</text>
|
||||
<text class="item-text">一等奖</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="relative mt30 m20lr">
|
||||
<image class="wp100" mode="widthFix" src="/static/image/index/tip.png"></image>
|
||||
<view class="title">活动说明</view>
|
||||
<view class="card">
|
||||
<view class="item-text">1. 中奖率100%</view>
|
||||
<view class="item-text">2. 报名后可获得一次抽奖机会</view>
|
||||
<view class="item-text">3. 中奖用户请于"我的-我的奖品"中查看并核销</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ScrapingCard from './scraping.vue'
|
||||
export default {
|
||||
components: {
|
||||
ScrapingCard
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
result: '特等奖',
|
||||
showBtn: true,
|
||||
winningList: [1,2,3,4,5,6,7,8]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleScrap() {
|
||||
this.showBtn = !this.showBtn
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.tip {
|
||||
position: relative;
|
||||
margin-top: -80px;
|
||||
margin-left: 40px;
|
||||
margin-right: 40px;
|
||||
height: 52rpx;
|
||||
background: rgba(0,0,0,0.5);
|
||||
border-radius: 26rpx;
|
||||
text-align: center;
|
||||
font-size: 24rpx;
|
||||
color: #fff;
|
||||
line-height: 52rpx;
|
||||
}
|
||||
.scraping {
|
||||
position: relative;
|
||||
margin-top: 20rpx;
|
||||
margin-left: 40px;
|
||||
margin-right: 40px;
|
||||
background-color: #fff;
|
||||
border: 3px solid #9e0f00; /* 实线边框 */
|
||||
border-top: 3px dashed #9e0f00; /* 虚线边框 */
|
||||
border-right: 3px dashed #9e0f00; /* 虚线边框 */
|
||||
border-bottom: 3px dashed #9e0f00; /* 虚线边框 */
|
||||
border-left: 3px dashed #9e0f00; /* 虚线边框 */
|
||||
border-radius: 5px; /* 圆角 */
|
||||
padding: 10px; /* 内容与边框之间的空间 */
|
||||
}
|
||||
.gj {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 21;
|
||||
.btn {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: calc(50% - 100rpx);
|
||||
width: 200rpx;
|
||||
height: 70rpx;
|
||||
line-height: 70rpx;
|
||||
background-color: #BE1200;
|
||||
border-radius: 10rpx;
|
||||
text-align: center;
|
||||
font-size: 28rpx;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
.title {
|
||||
position: absolute;
|
||||
left: calc(50% - 160rpx);
|
||||
top: -14px;
|
||||
width: 320rpx;
|
||||
height: 80rpx;
|
||||
line-height: 80rpx;
|
||||
text-align: center;
|
||||
background: linear-gradient(0deg, #ECB181, #FFEDD3);
|
||||
border: 6rpx solid #E32D1A;
|
||||
border-radius: 40rpx 40rpx 0 0;
|
||||
font-weight: 600;
|
||||
color: #BE1200;
|
||||
font-size: 32rpx;
|
||||
}
|
||||
.card {
|
||||
position: relative;
|
||||
margin-top: -40rpx;
|
||||
padding: 26rpx;
|
||||
min-height: 280rpx;
|
||||
background: #FFEDD3;
|
||||
border: 6rpx solid #E32D1A;
|
||||
border-radius: 24rpx;
|
||||
.card-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 80rpx;
|
||||
line-height: 80rpx;
|
||||
border-bottom: 1px solid #ecd3ae;
|
||||
}
|
||||
.card-item:last-of-type {
|
||||
border-bottom: none;
|
||||
}
|
||||
.item-text {
|
||||
font-size: 28rpx;
|
||||
color: #BE1200;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
266
src/pages/index/components/ggl/scraping.vue
Normal file
266
src/pages/index/components/ggl/scraping.vue
Normal file
@@ -0,0 +1,266 @@
|
||||
<template>
|
||||
<view class="scraping-happy" id="container">
|
||||
<canvas
|
||||
canvas-id="scraping-happy"
|
||||
class="scraping__canvas"
|
||||
:disable-scroll="true"
|
||||
@touchstart="touchstart"
|
||||
@touchmove="touchmove"
|
||||
@touchend="touchend"
|
||||
/>
|
||||
<cover-view class="scraping__view">
|
||||
{{ showText }}
|
||||
</cover-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/** @name 水印配置默认值 **/
|
||||
const WATERMARK = {
|
||||
text: '刮一刮',
|
||||
fontSize: 14,
|
||||
color: '#C5C5C5',
|
||||
}
|
||||
/** @name 标题配置默认值 **/
|
||||
const TITLE = {
|
||||
text: '刮一刮',
|
||||
fontSize: 16,
|
||||
color: '#333',
|
||||
}
|
||||
/**
|
||||
* @name 涂层配置默认值
|
||||
* @property { string } color 涂层颜色
|
||||
* @property { number } drawSize 清除涂层的画笔大小
|
||||
*/
|
||||
const MASK = {
|
||||
color: '#DDDDDD',
|
||||
drawSize: 20,
|
||||
}
|
||||
/** @name 容错值,解决部分机型涂层没有覆盖满的情况,主要原因是由于像素尺寸不同导致的,应尽可能让width与height保持整数 **/
|
||||
const TOLERANT = 3;
|
||||
|
||||
let ctx = null;
|
||||
|
||||
export default {
|
||||
props: {
|
||||
/** @name 涂层设置 **/
|
||||
mask: {
|
||||
type: [String, Object],
|
||||
},
|
||||
/** @name 水印设置 **/
|
||||
watermark: {
|
||||
type: [String, Object],
|
||||
},
|
||||
/** @name 提示文字 **/
|
||||
title: {
|
||||
type: [String, Object],
|
||||
},
|
||||
/** @name 刮开百分之多少直接消除图层,为0的时候不消除 **/
|
||||
percentage: {
|
||||
type: Number,
|
||||
default: 60,
|
||||
},
|
||||
result: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
width: 0,
|
||||
height: 0,
|
||||
touchX: 0,
|
||||
touchY: 0,
|
||||
showText: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
maskSetting() {
|
||||
return {
|
||||
...MASK,
|
||||
...(typeof this.mask === 'object' ? this.mask : { text: this.mask }),
|
||||
}
|
||||
},
|
||||
watermarkSetting() {
|
||||
return {
|
||||
...WATERMARK,
|
||||
...(typeof this.watermark === 'object' ? this.watermark : { text: this.watermark }),
|
||||
};
|
||||
},
|
||||
titleSetting() {
|
||||
return {
|
||||
...TITLE,
|
||||
...(typeof this.title === 'object' ? this.title : { text: this.title }),
|
||||
};
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
// 获取画布实例
|
||||
ctx = uni.createCanvasContext('scraping-happy', this);
|
||||
this.init();
|
||||
},
|
||||
methods: {
|
||||
/** @name 初始化 **/
|
||||
init() {
|
||||
const query = uni.createSelectorQuery().in(this);
|
||||
query
|
||||
.select('#container')
|
||||
.boundingClientRect(({ width, height }) => {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
setTimeout(() => {
|
||||
this.initCanvas();
|
||||
this.showText = this.result
|
||||
}, 20)
|
||||
})
|
||||
.exec();
|
||||
},
|
||||
/** @name 初始化canvas状态 **/
|
||||
initCanvas() {
|
||||
const { width, height } = this;
|
||||
// 清空矩形内容
|
||||
ctx.clearRect(0, 0, width, height);
|
||||
// 设置画笔颜色
|
||||
ctx.setFillStyle(this.maskSetting.color);
|
||||
// 绘制矩形
|
||||
ctx.fillRect(0, 0, width, height + TOLERANT);
|
||||
// 绘制水印
|
||||
this.drawWatermark();
|
||||
// 绘制提示文字
|
||||
this.drawTitle();
|
||||
// 绘制到canvas身上
|
||||
ctx.draw();
|
||||
},
|
||||
/** @name 绘制水印 **/
|
||||
drawWatermark() {
|
||||
if (!this.watermarkSetting.text) return;
|
||||
// 保存当前的绘图上下文
|
||||
ctx.save();
|
||||
// 旋转
|
||||
ctx.rotate((-10 * Math.PI) / 180);
|
||||
// 水印具体绘制过程
|
||||
const { width, height } = this;
|
||||
const watermarkWidth = this.watermarkSetting.text.length * this.watermarkSetting.fontSize;
|
||||
let x = 0;
|
||||
let y = 0;
|
||||
let i = 0;
|
||||
while ((x <= width * 5 || y <= height * 5) && i < 300) {
|
||||
ctx.setFillStyle(this.watermarkSetting.color);
|
||||
ctx.setFontSize(this.watermarkSetting.fontSize);
|
||||
ctx.fillText(this.watermarkSetting.text, x, y);
|
||||
x += watermarkWidth + watermarkWidth * 1.6;
|
||||
if (x > width && y <= height) {
|
||||
x = -Math.random() * 100;
|
||||
y += this.watermarkSetting.fontSize * 3;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
ctx.restore();
|
||||
},
|
||||
/** @name 绘制提示文字 **/
|
||||
drawTitle() {
|
||||
if (!this.titleSetting.text) return;
|
||||
ctx.setTextAlign('center');
|
||||
ctx.setTextBaseline('middle');
|
||||
ctx.setFillStyle(this.titleSetting.color);
|
||||
ctx.setFontSize(this.titleSetting.fontSize);
|
||||
ctx.fillText(this.titleSetting.text, this.width / 2, this.height / 3);
|
||||
},
|
||||
/** @name 触摸事件 **/
|
||||
touchstart(e) {
|
||||
this.touchX = e.touches[0].x;
|
||||
this.touchY = e.touches[0].y;
|
||||
},
|
||||
async touchmove(e) {
|
||||
// 把画笔到画布中的指定点
|
||||
ctx.moveTo(this.touchX, this.touchY);
|
||||
// 清除涂层
|
||||
ctx.clearRect(this.touchX, this.touchY, this.maskSetting.drawSize, this.maskSetting.drawSize);
|
||||
ctx.draw(true);
|
||||
// 记录移动点位
|
||||
this.touchX = e.touches[0].x;
|
||||
this.touchY = e.touches[0].y;
|
||||
|
||||
// if (this.percentage > 0) {
|
||||
// const clearPercent = await this.getClearMaskPercent();
|
||||
// }
|
||||
},
|
||||
async touchend() {
|
||||
if (this.percentage > 0) {
|
||||
const clearPercent = await this.getClearMaskPercent();
|
||||
if (clearPercent >= this.percentage) {
|
||||
ctx.moveTo(0, 0);
|
||||
ctx.clearRect(0, 0, this.width, this.height);
|
||||
ctx.stroke();
|
||||
ctx.draw(true);
|
||||
}
|
||||
}
|
||||
},
|
||||
/** @name 计算被清除的涂层百分比 **/
|
||||
getClearMaskPercent() {
|
||||
return new Promise(resolve => {
|
||||
uni.canvasGetImageData({
|
||||
canvasId: 'scraping-happy',
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: this.width,
|
||||
height: this.height,
|
||||
success: res => {
|
||||
// 区域内所有点的像素信息,它是一个数组,数组中每 "4" 项表示一个点的 rgba 值
|
||||
const allPointPixels = res.data;
|
||||
// 储存被清除的点-点的透明度
|
||||
const clearPoint = [];
|
||||
// 取透明度来判断,如果透明度值小于一半,则判断为该点已经被清除
|
||||
for (let i = 0; i < allPointPixels.length; i += 4) {
|
||||
if (allPointPixels[i + 3] < 128) {
|
||||
clearPoint.push(allPointPixels[i + 3]);
|
||||
}
|
||||
}
|
||||
// 已被清除的百分比 = 清除的点 / 全部的点
|
||||
const percent = (
|
||||
(clearPoint.length / (allPointPixels.length / 4)) *
|
||||
100
|
||||
).toFixed(2);
|
||||
resolve(percent);
|
||||
},
|
||||
fail: e => {
|
||||
console.log('canvasGetImageData', e);
|
||||
},
|
||||
}, this);
|
||||
});
|
||||
},
|
||||
/** @name 重置 **/
|
||||
reset() {
|
||||
this.initCanvas();
|
||||
this.touchX = 0;
|
||||
this.touchY = 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.scraping-happy {
|
||||
width: 100%;
|
||||
height: 200rpx;
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.scraping__canvas {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
/* background-color: red; */
|
||||
display: inline-block;
|
||||
}
|
||||
.scraping__view {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
color: #f29100;
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
@@ -11,6 +11,9 @@
|
||||
<u-sticky bgColor="#fff">
|
||||
<u-tabs :list="categoryList" :current="curTab" :scrollable="false" @change="changeCategory"></u-tabs>
|
||||
</u-sticky>
|
||||
<view class="m10tb">
|
||||
<u-swiper :list="activityList" @click="handleToActivity"></u-swiper>
|
||||
</view>
|
||||
<view style="background-color: rgb(245, 245, 245);">
|
||||
<template v-if="subject=='1' || subject=='4'">
|
||||
<Subject1 :subject="subject" :rightList="rightList" :wrongList="wrongList" />
|
||||
@@ -49,6 +52,7 @@
|
||||
categoryList: [],
|
||||
rightList: storage.get(`rightList_subject${this.subject}`) || [],
|
||||
wrongList: storage.get(`wrongList_subject${this.subject}`) || [],
|
||||
activityList: ['https://cdn.uviewui.com/uview/swiper/swiper1.png']
|
||||
};
|
||||
},
|
||||
onShow() {
|
||||
@@ -115,6 +119,12 @@
|
||||
}, 100)
|
||||
}
|
||||
},
|
||||
// 去活动
|
||||
handleToActivity(index) {
|
||||
uni.navigateTo({
|
||||
url: '/pages/index/activity'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -75,6 +75,11 @@
|
||||
<template #icon>
|
||||
<img src="/static/image/mine/wdzl.png" style="width: 24px;height: 24px;">
|
||||
</template>
|
||||
</u-cell>
|
||||
<u-cell size="large" title="我的奖品" isLink @tap="handleGift">
|
||||
<template #icon>
|
||||
<u-icon size="24" name="gift"></u-icon>
|
||||
</template>
|
||||
</u-cell>
|
||||
<u-cell size="large" title="我的体检" isLink @tap="handleTJ">
|
||||
<template #icon>
|
||||
@@ -224,6 +229,11 @@ export default {
|
||||
handleLogout() {
|
||||
useUserStore().logout()
|
||||
},
|
||||
handleGift() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/me/myGift'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
67
src/pages/me/myGift.vue
Normal file
67
src/pages/me/myGift.vue
Normal file
@@ -0,0 +1,67 @@
|
||||
<template>
|
||||
<view class="p10lr p20tb">
|
||||
<view v-for="(item, index) in list" :key="index" class="item">
|
||||
<view class="relative">
|
||||
<img src="/static/image/mine/giftitem.png" style="width: 100%;" mode="widthFix" alt="" />
|
||||
<view class="ab_full df ai-c jcc">一等奖</view>
|
||||
</view>
|
||||
<view class="df ai-c jcsb p20tb p10lr">
|
||||
<view class="item-label">
|
||||
<view>活动名称:幸运刮刮乐开心赢大奖</view>
|
||||
<view>参与时间:2024-01-01 08:00</view>
|
||||
<view>有效期至:2024-03-01 08:00</view>
|
||||
</view>
|
||||
<view class="ml20" style="width: 120rpx;">
|
||||
<img v-if="index%2==0" src="/static/image/mine/writeoff.png" style="width: 120rpx;height: 120rpx;" />
|
||||
<view v-else class="btn" @tap="handleWriteoff(item)">核销</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
list: []
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
this.handleSearch()
|
||||
},
|
||||
methods: {
|
||||
handleSearch() {
|
||||
this.list = [1,2,3,4,5]
|
||||
},
|
||||
handleWriteoff(item) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/me/qrCode?item=${item}`
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.item {
|
||||
margin-bottom: 30rpx;
|
||||
border-radius: 36rpx;
|
||||
background-color: #fff;
|
||||
.item-label {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
line-height: 48rpx;
|
||||
}
|
||||
.btn {
|
||||
width: 120rpx;
|
||||
height: 68rpx;
|
||||
text-align: center;
|
||||
line-height: 68rpx;
|
||||
border-radius: 34rpx;
|
||||
background-color: #BE1200;
|
||||
color: #fff;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
29
src/pages/me/qrCode.vue
Normal file
29
src/pages/me/qrCode.vue
Normal file
@@ -0,0 +1,29 @@
|
||||
<template>
|
||||
<view class="df jcc" style="padding-top: 100px;">
|
||||
<qrcode value="123" :size="200"/>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import qrcode from '/src/uni_modules/lime-qrcode/components/l-qrcode/l-qrcode.vue'
|
||||
export default {
|
||||
components: {
|
||||
qrcode
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
value: ''
|
||||
}
|
||||
},
|
||||
onLoad(option) {
|
||||
this.value = option.item
|
||||
},
|
||||
methods: {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
Reference in New Issue
Block a user