diff --git a/.env.development b/.env.development index 52702e2..bf60e6e 100644 --- a/.env.development +++ b/.env.development @@ -7,4 +7,6 @@ VITE_APP_ENV = 'development' # 金武联驾校/开发环境 VITE_APP_BASE_API = 'https://jwl.ahduima.com/' # -VITE_WEB_BASE_URL = 'https://jwl.ahduima.com' \ No newline at end of file +VITE_WEB_BASE_URL = 'https://jwl.ahduima.com' +# 资源地址 +VITE_RESOURSE_URL = 'http://huodong.ahduima.com' \ No newline at end of file diff --git a/.env.production b/.env.production index ea53d5b..297da09 100644 --- a/.env.production +++ b/.env.production @@ -9,3 +9,6 @@ VITE_APP_BASE_API = 'https://jwl.ahduima.com/' # VITE_WEB_BASE_URL = 'https://jwl.ahduima.com' + +# 资源地址 +VITE_RESOURSE_URL = 'http://huodong.ahduima.com' \ No newline at end of file diff --git a/src/jtools/api/activity.js b/src/jtools/api/activity.js new file mode 100644 index 0000000..0cdffa5 --- /dev/null +++ b/src/jtools/api/activity.js @@ -0,0 +1,75 @@ +import request from '../request/index.js'; + +//查询活动列表 +export function queryActivityList(data) { + return request({ + url: 'activity/applet/activity/list', + method: 'get', + data, + noToken: true + }); +} +//查询活动详情 +export function queryActivityDetail(data) { + return request({ + url: 'activity/applet/activity/detail', + method: 'get', + data, + noToken: true + }); +} +//查询抽奖次数 +export function queryLuckyNum(data) { + return request({ + url: 'activity/applet/activity/lucky/num', + method: 'get', + data, + noToken: true + }); +} +//查询中奖结果 +export function queryLuckyResult(data) { + return request({ + url: 'activity/applet/activity/lucky/result', + method: 'get', + data, + noToken: true + }); +} +//录入中奖结果 +export function saveWinner(data) { + return request({ + url: 'activity/applet/activity/winner/save', + method: 'POST', + data, + noToken: true + }); +} +//核销 +export function receiveWinner(data) { + return request({ + url: 'activity/applet/activity/winner/receive', + method: 'POST', + data, + noToken: true + }); +} +//查询中奖记录 +export function getLuckyRecord(data) { + return request({ + url: 'activity/applet/activity/lucky/record', + method: 'get', + data, + noToken: true + }); +} + +//查询中奖记录 +export function canRecieveGift(data) { + return request({ + url: 'activity/applet/activity/receive/user', + method: 'get', + data, + noToken: true + }); +} \ No newline at end of file diff --git a/src/jtools/request/index.js b/src/jtools/request/index.js index 25d87b1..1ab1d45 100644 --- a/src/jtools/request/index.js +++ b/src/jtools/request/index.js @@ -32,7 +32,7 @@ function service(options = {}) { useUserStore().logoutWithoutToken() //请求成功 resolved(res.data); - } else if(res.data.code != '0000'&&res.data.code !='4001') { + } else if(res.data.code != '0000'&&res.data.code !='4001'&&res.data.code != 200) { uni.showToast({ title: res?.data?.message || '访问出错', icon: 'none' diff --git a/src/pages/index/components/ggl/index.vue b/src/pages/index/components/ggl/index.vue index 3847459..58c9c06 100644 --- a/src/pages/index/components/ggl/index.vue +++ b/src/pages/index/components/ggl/index.vue @@ -1,22 +1,23 @@ <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="tip">您今日还剩{{actiNum}}次刮奖机会,共有{{total}}人参加活动</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> + <scraping-card style="z-index: 20;" :result="result" watermark="刮一刮" title="刮一刮赢取大奖" ref="reset" @complete="handleComplete" > + <cover-view v-if="showBtn" class="gj"> + <cover-view class="btn" @tap="handleScrap"> + {{btnText}} + </cover-view> + </cover-view> + </scraping-card> </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> + <text class="item-text">{{ hidePhoneNumber(item.phone) }}</text> + <text class="item-text">{{ item.awards }}</text> </view> </view> </view> @@ -24,35 +25,113 @@ <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> + <u-parse :content="activityRule"></u-parse> </view> </view> </view> </template> <script> + import useUserStore from '@/jtools/store/user' import ScrapingCard from './scraping.vue' + import { queryActivityDetail,queryLuckyNum,queryLuckyResult,saveWinner,getLuckyRecord } from '@/jtools/api/activity' export default { components: { ScrapingCard }, data() { return { - result: '特等奖', + detailId: undefined, + result: '', + btnText: '点我刮奖', showBtn: true, - winningList: [1,2,3,4,5,6,7,8] + actiNum: 0, + total: 0, + winningList: [], + activityRule: undefined } }, + onLoad(op) { + this.detailId = op.detailId + this.getActivityDetail() + this.getActivityNum() + this.searchWinningList() + }, methods: { handleScrap() { - this.showBtn = !this.showBtn + if(!this.actiNum) { + uni.showToast({ + icon: 'none', + title: '暂无抽奖机会' + }) + return + } + + queryLuckyResult({ + detailId: this.detailId + }).then(resp => { + if(resp.code == 200) { + this.result = resp.msg + this.showBtn = !this.showBtn + this.$refs.reset.init() + } + }) + }, + getActivityDetail() { + queryActivityDetail({detailId: this.detailId}).then(resp => { + if(resp.code == 200) { + this.activityRule = resp.data.activity.activityRule + } + }) + }, + hidePhoneNumber(phoneNumber) { + // 验证电话号码格式 + if (!/^\d{11}$/.test(phoneNumber)) { + return "无效的电话号码"; + } + + // 替换中间四位数字为星号 + return phoneNumber.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2'); + }, + getActivityNum() { + queryLuckyNum({ + detailId: this.detailId, + phone: useUserStore().userInfo?.phone || '' + }).then(resp => { + if(resp.code == 200) { + this.actiNum = resp.data.drawNum + this.total = resp.data.totalPeople + } + }) + }, + searchWinningList() { + getLuckyRecord({ + detailId: this.detailId, + pageSize: 8 + }).then(resp => { + if(resp.code == 200) { + this.winningList = resp.rows + } + }) + }, + handleComplete() { + saveWinner({ + phone: useUserStore().userInfo?.phone || '', + detailId: this.detailId, + awards: this.result + }).then(resp => { + this.btnText = '再刮一次!' + if(resp.code == 200) { + this.getActivityNum() + uni.showToast({ + icon: 'none', + title: `恭喜获得${this.result}` + }) + this.showBtn = true + } + }) } }, - mounted() { - - } } </script> diff --git a/src/pages/index/components/ggl/scraping.vue b/src/pages/index/components/ggl/scraping.vue index 652324d..9703c34 100644 --- a/src/pages/index/components/ggl/scraping.vue +++ b/src/pages/index/components/ggl/scraping.vue @@ -1,266 +1,280 @@ <template> <view class="scraping-happy" id="container"> - <canvas - canvas-id="scraping-happy" - class="scraping__canvas" - :disable-scroll="true" - @touchstart="touchstart" - @touchmove="touchmove" - @touchend="touchend" - /> + <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> + <slot></slot> </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; + /** @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; + 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 }), + export default { + props: { + /** @name 涂层设置 **/ + mask: { + type: [String, Object], + }, + /** @name 水印设置 **/ + watermark: { + type: [String, Object], + }, + /** @name 提示文字 **/ + title: { + type: [String, Object], + }, + /** @name 刮开百分之多少直接消除图层,为0的时候不消除 **/ + percentage: { + type: Number, + default: 40, + }, + result: { + type: String, + default: '' } }, - watermarkSetting() { + data() { 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(); + width: 0, + height: 0, + touchX: 0, + touchY: 0, + showText: '' + } }, - /** @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; + computed: { + maskSetting() { + return { + ...MASK, + ...(typeof this.mask === 'object' ? this.mask : { + text: this.mask + }), } - i++; + }, + watermarkSetting() { + return { + ...WATERMARK, + ...(typeof this.watermark === 'object' ? this.watermark : { + text: this.watermark + }), + }; + }, + titleSetting() { + return { + ...TITLE, + ...(typeof this.title === 'object' ? this.title : { + text: this.title + }), + }; } - 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; + mounted() { + // 获取画布实例 + ctx = uni.createCanvasContext('scraping-happy', this); + this.init(); }, - 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; + 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); + // 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); + this.$emit('complete') + } } - } - }, - /** @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]); + }, + /** @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; + // 已被清除的百分比 = 清除的点 / 全部的点 + 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> + .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; + letter-spacing: 8px; + } +</style> \ No newline at end of file diff --git a/src/pages/index/index.vue b/src/pages/index/index.vue index 83f128d..a43679b 100644 --- a/src/pages/index/index.vue +++ b/src/pages/index/index.vue @@ -1,137 +1,165 @@ <template> - <view> - <view v-if="getLoading" class="wp100 relative" style="height: 100vh;"> - <image class="wp100" mode="widthFix" src="https://oss-bq.ahduima.com/%E5%B0%8F%E7%A8%8B%E5%BA%8F/%E5%9B%BE%E7%89%87/%E8%80%83%E8%AF%95%E6%8F%90%E9%86%92_20230906135037.png"></image> - <view class="wp100 flex ai-c jc-c" style="position: absolute;bottom: 0;left: 0;padding-bottom: 124rpx;"> - <image style="width: 452rpx;" src="https://oss-bq.ahduima.com/%E5%B0%8F%E7%A8%8B%E5%BA%8F/%E5%9B%BE%E7%89%87/%E9%87%91%E6%AD%A6%E8%81%94_20230831123333.png" mode="widthFix"></image> - </view> - </view> - <view v-if="!getLoading"> - <j-navbar :isBack="false">金武联驾考</j-navbar> - <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 v-if="getLoading" class="wp100 relative" style="height: 100vh;"> + <image class="wp100" mode="widthFix" + src="https://oss-bq.ahduima.com/%E5%B0%8F%E7%A8%8B%E5%BA%8F/%E5%9B%BE%E7%89%87/%E8%80%83%E8%AF%95%E6%8F%90%E9%86%92_20230906135037.png"> + </image> + <view class="wp100 flex ai-c jc-c" style="position: absolute;bottom: 0;left: 0;padding-bottom: 124rpx;"> + <image style="width: 452rpx;" + src="https://oss-bq.ahduima.com/%E5%B0%8F%E7%A8%8B%E5%BA%8F/%E5%9B%BE%E7%89%87/%E9%87%91%E6%AD%A6%E8%81%94_20230831123333.png" + mode="widthFix"></image> </view> - <view style="background-color: rgb(245, 245, 245);"> - <template v-if="subject=='1' || subject=='4'"> - <Subject1 :subject="subject" :rightList="rightList" :wrongList="wrongList" /> - </template> - <template v-else> - <Subject2 :subject="subject" ref="subjectRef" /> - </template> - </view> - </view> - </view> + </view> + <view v-if="!getLoading"> + <j-navbar :isBack="false">金武联驾考</j-navbar> + <u-sticky bgColor="#fff"> + <u-tabs :list="categoryList" :current="curTab" :scrollable="false" @change="changeCategory"></u-tabs> + </u-sticky> + <view class="m10tb" v-if="activityList&&activityList.length"> + <u-swiper class="acticity" keyName="image" :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" /> + </template> + <template v-else> + <Subject2 :subject="subject" ref="subjectRef" /> + </template> + </view> + </view> + </view> </template> <script> - import { - mapState, - mapActions - } from 'pinia' //引入映射函数 - import useQuestionStore from '@/jtools/store/question' //引入store - import storage from '@/jtools/storage'; - import { - querySysConfigList, - } from '@/jtools/api/question'; - import Subject1 from "./components/Subject1"; - import Subject2 from "./components/Subject2"; - export default { - components: { - Subject1, - Subject2 - }, - data() { - return { - show:false, - subject: storage.get('curSubject') || '1', - curTab: 0, - searchValue: '', - cityName: '', - 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() { - this.show=true - this.getSubjectConfig() - if (this.subject == '1' || this.subject == '4') { - this.rightList = storage.get(`rightList_subject${this.subject}`) || [] - this.wrongList = storage.get(`wrongList_subject${this.subject}`) || [] - } - if(this.subject=='2'||this.subject=='3'){ - this.$refs.subjectRef.getDiverType() - } - }, - onHide(){ - this.show=false - }, - computed: { - ...mapState(useQuestionStore, ["loading_subject4", "loading_subject1","curSubject","orderQuestion_subject1","orderQuestion_subject4"]), //映射函数,取出tagslist - getLoading() { - return this.loading_subject4 && this.loading_subject1 - } - }, - watch:{ - getLoading(newVal){ - if(this.show){ - if(newVal){ - if(this.loading_subject4 && this.loading_subject1){ - uni.hideTabBar(); - } - }else{ - uni.showTabBar() - } - } - } - }, - methods: { - ...mapActions(useQuestionStore, ['getOrderQuestion_sub4', 'getOrderQuestion_sub1', 'changeSubject']), - //获取科目配置 - getSubjectConfig() { - const carTypeId = storage.get('carType') || '1001' - querySysConfigList(carTypeId, 'Subject').then(resp => { - if (resp.code === '0000') { - this.categoryList = resp.data.map(item => { - return { - ...item, - name: item.configItemName - } - }) - this.subject=storage.get('curSubject') || '1', - this.curTab=this.categoryList.findIndex(item=>item.configItemCode==this.subject) - } - }) - }, - //切换科目 - async changeCategory(val) { - this.subject = val.configItemCode - this.changeSubject(this.subject) - if (this.subject == '1' || this.subject == '4') { - this.rightList = storage.get(`rightList_subject${this.subject}`) || [] - this.wrongList = storage.get(`wrongList_subject${this.subject}`) || [] - } else { - setTimeout(() => { - this.$refs.subjectRef.getDiverType() - }, 100) - } - }, + import { + mapState, + mapActions + } from 'pinia' //引入映射函数 + import useQuestionStore from '@/jtools/store/question' //引入store + import useUserStore from '@/jtools/store/user' + import storage from '@/jtools/storage'; + import { + querySysConfigList, + } from '@/jtools/api/question'; + import Subject1 from "./components/Subject1"; + import Subject2 from "./components/Subject2"; + import { + queryActivityList + } from '@/jtools/api/activity'; + export default { + components: { + Subject1, + Subject2 + }, + data() { + return { + show: false, + subject: storage.get('curSubject') || '1', + curTab: 0, + searchValue: '', + cityName: '', + categoryList: [], + rightList: storage.get(`rightList_subject${this.subject}`) || [], + wrongList: storage.get(`wrongList_subject${this.subject}`) || [], + activityList: [] + }; + }, + onShow() { + this.show = true + this.getSubjectConfig() + if (this.subject == '1' || this.subject == '4') { + this.rightList = storage.get(`rightList_subject${this.subject}`) || [] + this.wrongList = storage.get(`wrongList_subject${this.subject}`) || [] + } + if (this.subject == '2' || this.subject == '3') { + this.$refs.subjectRef.getDiverType() + } + this.queryActivityList() + }, + onHide() { + this.show = false + }, + computed: { + ...mapState(useQuestionStore, ["loading_subject4", "loading_subject1", "curSubject", "orderQuestion_subject1", + "orderQuestion_subject4" + ]), //映射函数,取出tagslist + getLoading() { + return this.loading_subject4 && this.loading_subject1 + } + }, + watch: { + getLoading(newVal) { + if (this.show) { + if (newVal) { + if (this.loading_subject4 && this.loading_subject1) { + uni.hideTabBar(); + } + } else { + uni.showTabBar() + } + } + } + }, + methods: { + ...mapActions(useQuestionStore, ['getOrderQuestion_sub4', 'getOrderQuestion_sub1', 'changeSubject']), + //获取科目配置 + getSubjectConfig() { + const carTypeId = storage.get('carType') || '1001' + querySysConfigList(carTypeId, 'Subject').then(resp => { + if (resp.code === '0000') { + this.categoryList = resp.data.map(item => { + return { + ...item, + name: item.configItemName + } + }) + this.subject = storage.get('curSubject') || '1', + this.curTab = this.categoryList.findIndex(item => item.configItemCode == this.subject) + } + }) + }, + //切换科目 + async changeCategory(val) { + this.subject = val.configItemCode + this.changeSubject(this.subject) + if (this.subject == '1' || this.subject == '4') { + this.rightList = storage.get(`rightList_subject${this.subject}`) || [] + this.wrongList = storage.get(`wrongList_subject${this.subject}`) || [] + } else { + setTimeout(() => { + this.$refs.subjectRef.getDiverType() + }, 100) + } + }, + //查询活动列表 + queryActivityList() { + queryActivityList({ + schoolId: useUserStore().userInfo?.schoolId || '' + }).then(resp => { + this.activityList = resp.data.map(item => ({ + ...item, + image: 'https://jwl.ahduima.com' + item.image + })); + }) + }, // 去活动 handleToActivity(index) { + let detailId; + this.activityList.find((item, index1) => { + if (index === index1) { + detailId = item.detailId; + } + }) uni.navigateTo({ - url: '/pages/index/activity' + url: '/pages/index/activity?detailId=' + detailId, }) } - } - } + } + } </script> <style lang="scss" scoped> - ::v-deep .u-tabs__wrapper__nav__line { - background: linear-gradient(90deg, #11DF20 0%, #00B74F 100%) !important; - bottom: 14rpx !important; - } + ::v-deep .u-tabs__wrapper__nav__line { + background: linear-gradient(90deg, #11DF20 0%, #00B74F 100%) !important; + bottom: 14rpx !important; + } </style> \ No newline at end of file diff --git a/src/pages/login/login.vue b/src/pages/login/login.vue index 9939448..7eec0c0 100644 --- a/src/pages/login/login.vue +++ b/src/pages/login/login.vue @@ -7,11 +7,11 @@ <view class="list"> <view class="list-call"> - <u-input class="sl-input" border="none" v-model="login.phone" type="number" maxlength="11" + <u-input class="sl-input" border="none" v-model="loginForm.phone" type="number" maxlength="11" placeholder="输入手机号" /> </view> <view class="list-call"> - <u-input class="sl-input" v-model="login.code" type="text" maxlength="6" border="none" placeholder="输入验证码"> + <u-input class="sl-input" v-model="loginForm.code" type="text" maxlength="6" border="none" placeholder="输入验证码"> <template #suffix> <text class="fs14 mr10" style="color: #05C341;" @tap="getCode">{{ countDown == 0 ? '获取验证码' : countDown }}</text> </template> @@ -39,7 +39,7 @@ import storage from '@/jtools/storage'; export default { data() { return { - login: { + loginForm: { phone: '', code: '' }, @@ -54,9 +54,9 @@ export default { }, methods: { getCode() { - if (isPhone(this.login.phone) && this.countDown == 0) { + if (isPhone(this.loginForm.phone) && this.countDown == 0) { getCode({ - phone: this.login.phone + phone: this.loginForm.phone }).then(resp => { // if (resp.code == '0000') { uni.showToast({ @@ -80,8 +80,8 @@ export default { this.countDown = 0 }, bindLogin() { - if (isPhone(this.login.phone) && this.login.code) { - let params = { ...this.login } + if (isPhone(this.loginForm.phone) && this.loginForm.code) { + let params = { ...this.loginForm } if (storage.get('companyId')) { params.id = storage.get('companyId') } diff --git a/src/pages/me/index.vue b/src/pages/me/index.vue index b8e4d21..e1c3942 100644 --- a/src/pages/me/index.vue +++ b/src/pages/me/index.vue @@ -12,6 +12,9 @@ </view> <view class="mt5 fs14 cor-666">陪您学车 第{{ user.days }}天</view> </view> + <view v-if="canRecieve" class="ml20 p20" @tap="handleScan"> + <u-icon name="scan" size="40"></u-icon> + </view> </view> <view class="info flex ai-c" v-else @tap="toLogin"> <u-avatar class="br-p50 overflow-h" :size="64" src="@/static/image/mine/default_avatar.png" shape="circle"></u-avatar> @@ -107,8 +110,8 @@ <script> import useUserStore from '@/jtools/store/user' import storage from '@/jtools/storage'; +import { receiveWinner,canRecieveGift } from '@/jtools/api/activity' export default { - components: {}, computed: { isLogin() { return useUserStore().isLogin @@ -148,14 +151,25 @@ export default { data() { return { carName: storage.get('carName') || '小车C1/C2/C3', - isIOS: true + isIOS: true, + canRecieve: false } }, onShow() { this.isIOS = this.$platform.device().includes('ios') this.carName = storage.get('carName') || '小车C1/C2/C3' + this.searchActivityAuth() }, methods: { + searchActivityAuth() { + canRecieveGift({ + phone: useUserStore().userInfo?.phone || '' + }).then(resp => { + if(resp.code == 200) { + this.canRecieve = resp.data + } + }) + }, // 拨打电话 callPhoneNumber() { uni.makePhoneCall({ @@ -233,6 +247,25 @@ export default { uni.navigateTo({ url: '/pages/me/myGift' }) + }, + handleScan() { + uni.scanCode({ + scanType: ['qrCode'], + success(res) { + console.log('条码内容:' + res.result); + receiveWinner({ + id: res.result, + receiveUser: useUserStore().userInfo?.phone || [] + }).then(resp => { + if(resp.code == 200) { + uni.showToast({ + icon: 'none', + title: '核销成功!' + }) + } + }) + } + }) } } } diff --git a/src/pages/me/myGift.vue b/src/pages/me/myGift.vue index 4b13133..6161c67 100644 --- a/src/pages/me/myGift.vue +++ b/src/pages/me/myGift.vue @@ -1,44 +1,66 @@ <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> + <u-list @scrolltolower="loadmore"> + <u-list-item 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">{{item.awards}}</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 class="df ai-c jcsb p20tb p10lr"> + <view class="item-label"> + <view>活动名称:{{ item.activityName }}</view> + <view>参与时间:{{ item.createTime }}</view> + <view>有效期至:{{ item.endTime }}</view> + </view> + <view class="ml20" style="width: 120rpx;"> + <img v-if="item.status" src="/static/image/mine/writeoff.png" style="width: 120rpx;height: 120rpx;" /> + <view v-else class="btn" @tap="handleWriteoff(item)">核销</view> + </view> </view> - </view> - </view> + </u-list-item> + </u-list> </view> </template> <script> + import useUserStore from '@/jtools/store/user' + import { getLuckyRecord } from '@/jtools/api/activity' export default { data() { return { + pageNum: 1, list: [] } }, onShow() { + this.pageNum = 1 + this.list = [] this.handleSearch() }, methods: { handleSearch() { - this.list = [1,2,3,4,5] + getLuckyRecord({ + phone: useUserStore().userInfo.phone, + pageSize: 10, + pageNum: this.pageNum + }).then(resp => { + if(resp.code == 200) { + if(resp.rows && resp.rows.length) { + this.list = [...this.list, ...resp.rows] + } else { + this.pageNum = this.pageNum > 1 ? this.pageNum-1 : 1 + } + } + }) + }, + loadmore() { + this.handleSearch(this.pageNum++) }, handleWriteoff(item) { uni.navigateTo({ - url: `/pages/me/qrCode?item=${item}` + url: `/pages/me/qrCode?id=${item.id}` }) - } + }, } } </script> diff --git a/src/pages/me/qrCode.vue b/src/pages/me/qrCode.vue index ce5d803..fb75942 100644 --- a/src/pages/me/qrCode.vue +++ b/src/pages/me/qrCode.vue @@ -1,6 +1,6 @@ <template> <view class="df jcc" style="padding-top: 100px;"> - <qrcode value="123" :size="200"/> + <qrcode v-if="value" :value="value" :size="200"/> </view> </template> @@ -16,11 +16,8 @@ } }, onLoad(option) { - this.value = option.item + this.value = option.id }, - methods: { - - } } </script>