initial commit: giftlaw ni xue fa wo you li - natural resources session
This commit is contained in:
@@ -0,0 +1,219 @@
|
||||
<template>
|
||||
<view class="content">
|
||||
<image src="https://aliyunoss.hn12301.net/learnlaw/gift_zt_bj.jpg" mode="widthFix" style="width:750rpx;position:absolute;top:0;left:0;z-index:-1;"></image>
|
||||
<view class="page-body">
|
||||
<view class="loading-box" v-if="!loaded && !loadError">
|
||||
<u-loading mode="circle" size="40"></u-loading>
|
||||
<text class="loading-text">加载中...</text>
|
||||
</view>
|
||||
<view class="loading-box" v-if="loadError">
|
||||
<text class="error-text">{{ loadError }}</text>
|
||||
<button class="retry-btn" @tap="fetchRecords">重新加载</button>
|
||||
</view>
|
||||
<view class="empty-box" v-if="loaded && records.length === 0 && !loadError">
|
||||
<text class="empty-icon">📝</text>
|
||||
<text class="empty-text">暂无答题记录</text>
|
||||
</view>
|
||||
<template v-if="records.length > 0">
|
||||
<view class="record-item" v-for="(item, i) in records" :key="item.id" @click="goDetail(item)">
|
||||
<view class="record-index">
|
||||
<text class="record-index-text">{{ i + 1 }}</text>
|
||||
</view>
|
||||
<view class="record-body">
|
||||
<view class="record-row">
|
||||
<text class="record-label">答题时间:</text>
|
||||
<text class="record-value">{{ item.create_time }}</text>
|
||||
</view>
|
||||
<view class="record-row">
|
||||
<text class="record-label">答对题数:</text>
|
||||
<text class="record-value">{{ item.correct_question_num }} / {{ item.total_question_num }} 题</text>
|
||||
</view>
|
||||
<view class="record-row">
|
||||
<text class="record-label">答题用时:</text>
|
||||
<text class="record-value">{{ formatTime(item.use_time) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
records: [],
|
||||
loaded: false,
|
||||
loadError: ''
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
this.fetchRecords()
|
||||
},
|
||||
methods: {
|
||||
fetchRecords() {
|
||||
this.loadError = ''
|
||||
const userId = uni.getStorageSync('userIdGift')
|
||||
if (!userId) {
|
||||
this.loadError = '暂未登录'
|
||||
return
|
||||
}
|
||||
this.$u.api.getUserHisResultList({
|
||||
wenjuanId: 1003,
|
||||
userId: userId
|
||||
}).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.records = res.Data?.result_list || []
|
||||
this.loaded = true
|
||||
} else {
|
||||
this.loadError = res.msg || '数据异常'
|
||||
}
|
||||
}).catch(err => {
|
||||
console.error('获取答题记录失败', err)
|
||||
this.loadError = '网络请求失败'
|
||||
})
|
||||
},
|
||||
formatTime(sec) {
|
||||
const m = Math.floor(sec / 60)
|
||||
const s = sec % 60
|
||||
return (m < 10 ? '0' : '') + m + ':' + (s < 10 ? '0' : '') + s
|
||||
},
|
||||
goDetail(item) {
|
||||
uni.navigateTo({
|
||||
url: '/pages/record-detail/record-detail?resultId=' + item.id
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: #7CC6EB;
|
||||
}
|
||||
|
||||
.content {
|
||||
position: relative;
|
||||
min-height: 100vh;
|
||||
min-height: 100dvh;
|
||||
}
|
||||
|
||||
.page-body {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
min-height: 100vh;
|
||||
min-height: 100dvh;
|
||||
padding: 40rpx 30rpx;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.record-item {
|
||||
background: rgba(255,255,255,0.95);
|
||||
border-radius: 20rpx;
|
||||
padding: 28rpx;
|
||||
margin-bottom: 20rpx;
|
||||
display: flex;
|
||||
box-shadow: 0 2rpx 12rpx rgba(0,0,0,0.04);
|
||||
}
|
||||
|
||||
.record-index {
|
||||
width: 44rpx;
|
||||
height: 44rpx;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(135deg, #FD5401, #FF7A3D);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
margin-right: 16rpx;
|
||||
margin-top: 2rpx;
|
||||
box-shadow: 0 2rpx 8rpx rgba(253,84,1,0.3);
|
||||
}
|
||||
|
||||
.record-index-text {
|
||||
font-size: 20rpx;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.record-body {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.record-row {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
margin-top: 6rpx;
|
||||
}
|
||||
|
||||
.record-row:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.record-label {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.record-value {
|
||||
font-size: 26rpx;
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.loading-box {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.loading-text {
|
||||
font-size: 28rpx;
|
||||
color: #fff;
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
|
||||
.error-text {
|
||||
font-size: 28rpx;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.retry-btn {
|
||||
margin-top: 30rpx;
|
||||
width: 240rpx;
|
||||
height: 72rpx;
|
||||
line-height: 72rpx;
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
color: #FD5401;
|
||||
border: none;
|
||||
border-radius: 36rpx;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.empty-box {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.empty-icon {
|
||||
font-size: 80rpx;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
font-size: 26rpx;
|
||||
color: rgba(255,255,255,0.7);
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,404 @@
|
||||
<template>
|
||||
<view class="content">
|
||||
<view class="page-body">
|
||||
<view class="loading-box" v-if="questions.length === 0 && !loadError">
|
||||
<u-loading mode="circle" size="40"></u-loading>
|
||||
<text class="loading-text">加载题目中...</text>
|
||||
</view>
|
||||
<view class="loading-box" v-if="loadError">
|
||||
<text class="error-text">{{ loadError }}</text>
|
||||
<button class="retry-btn" @tap="fetchQuestions">重新加载</button>
|
||||
</view>
|
||||
<template v-if="questions.length > 0">
|
||||
<image src="https://aliyunoss.hn12301.net/learnlaw/gift_zt_bj.jpg" mode="widthFix" style="width:750rpx;"></image>
|
||||
<view style="position:absolute;top:200rpx;left:0;z-index:0;padding: 30rpx;" >
|
||||
<view class="quiz-header">
|
||||
<view class="timer-wrap">
|
||||
<text class="timer-label">答题时间</text>
|
||||
<text class="timer">{{ formatTime(usedSeconds) }}</text>
|
||||
</view>
|
||||
<text class="answered-count">已答 {{ answeredCount }} / {{ questions.length }}</text>
|
||||
</view>
|
||||
|
||||
|
||||
<view class="question-item" v-for="(q, qi) in questions" :key="q.question_id">
|
||||
<view class="q-header">
|
||||
<text class="q-index">{{ qi + 1 }}</text>
|
||||
<text class="q-content">{{ q.question_content }}</text>
|
||||
</view>
|
||||
<view class="options">
|
||||
<view
|
||||
class="option"
|
||||
v-for="(opt, oi) in q.answerList"
|
||||
:key="opt.id"
|
||||
:class="{ selected: answers[q.question_id] === oi }"
|
||||
@tap="select(q.question_id, oi)"
|
||||
>
|
||||
<view class="option-radio" :class="{ checked: answers[q.question_id] === oi }">
|
||||
<view v-if="answers[q.question_id] === oi" class="radio-dot"></view>
|
||||
</view>
|
||||
<text class="option-text">{{ opt.answer_content }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="tips" v-if="answers[q.question_id] !== undefined">
|
||||
<text class="tips-label">解析</text>
|
||||
<text class="tips-text">{{ q.tips }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<button class="submit-btn" @tap="submit">提交</button>
|
||||
</view>
|
||||
|
||||
|
||||
</template>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
questions: [],
|
||||
answers: {},
|
||||
loadError: '',
|
||||
startTime: 0,
|
||||
usedSeconds: 0,
|
||||
timer: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
answeredCount() {
|
||||
return Object.keys(this.answers).length
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
this.fetchQuestions()
|
||||
},
|
||||
onUnload() {
|
||||
this.stopTimer()
|
||||
},
|
||||
methods: {
|
||||
fetchQuestions() {
|
||||
this.loadError = ''
|
||||
if (uni.getStorageSync('userIdGift')) {
|
||||
this.doFetchQuestions()
|
||||
return
|
||||
}
|
||||
const openId = uni.getStorageSync('openIdGift')
|
||||
if (!openId) {
|
||||
this.loadError = '未获取到用户信息,请返回首页重新进入'
|
||||
return
|
||||
}
|
||||
this.$u.api.wxOpenidLogin({ wenjuan_id: 1003, open_id: openId }).then(loginRes => {
|
||||
if (loginRes && loginRes.code === 0 && loginRes.Data && loginRes.Data.user_name && loginRes.Data.user_phone) {
|
||||
uni.setStorageSync('isRegisteredGift', true)
|
||||
uni.setStorageSync('userIdGift', loginRes.Data.user_id || loginRes.Data.uesr_id)
|
||||
uni.setStorageSync('userNameGift', loginRes.Data.user_name)
|
||||
uni.setStorageSync('userPhoneGift', loginRes.Data.user_phone)
|
||||
}
|
||||
if (!uni.getStorageSync('userIdGift')) {
|
||||
this.loadError = '未获取到用户信息,请返回首页重新进入'
|
||||
return
|
||||
}
|
||||
this.doFetchQuestions()
|
||||
}).catch(err => {
|
||||
console.error('同步用户信息失败', err)
|
||||
this.loadError = '网络请求失败'
|
||||
})
|
||||
},
|
||||
doFetchQuestions() {
|
||||
const userId = uni.getStorageSync('userIdGift')
|
||||
const userPhone = uni.getStorageSync('userPhoneGift')
|
||||
this.$u.api.queryWenjuanQA({
|
||||
wenjuan_id: 1003,
|
||||
user_id: userId,
|
||||
user_phone: userPhone
|
||||
}).then(res => {
|
||||
if (res.code === 0 && res.Data?.wenjuanTmList) {
|
||||
this.questions = res.Data.wenjuanTmList
|
||||
this.startTimer()
|
||||
} else {
|
||||
this.loadError = res.msg || '数据异常'
|
||||
}
|
||||
}).catch(err => {
|
||||
console.error('获取题目失败', err)
|
||||
this.loadError = '网络请求失败'
|
||||
})
|
||||
},
|
||||
startTimer() {
|
||||
this.startTime = Date.now()
|
||||
this.timer = setInterval(() => {
|
||||
this.usedSeconds = (Date.now() - this.startTime) / 1000
|
||||
}, 100)
|
||||
},
|
||||
stopTimer() {
|
||||
if (this.timer) {
|
||||
clearInterval(this.timer)
|
||||
this.timer = null
|
||||
}
|
||||
},
|
||||
formatTime(sec) {
|
||||
const m = Math.floor(sec / 60)
|
||||
const sFloat = sec - m * 60
|
||||
const s = Math.floor(sFloat)
|
||||
const cs = Math.floor((sFloat - s) * 100)
|
||||
return (m < 10 ? '0' : '') + m + ':' + (s < 10 ? '0' : '') + s + '.' + (cs < 10 ? '0' : '') + cs
|
||||
},
|
||||
select(qId, oi) {
|
||||
this.$set(this.answers, qId, oi)
|
||||
},
|
||||
submit() {
|
||||
if (this.answeredCount < this.questions.length) {
|
||||
uni.showToast({ title: '还有题目未作答', icon: 'none' })
|
||||
return
|
||||
}
|
||||
const elapsed = Math.round((Date.now() - this.startTime) / 1000 * 100) / 100
|
||||
if (elapsed < 9) {
|
||||
uni.showToast({ title: '操作繁忙,请重试', icon: 'none' })
|
||||
return
|
||||
}
|
||||
this.stopTimer()
|
||||
const userId = uni.getStorageSync('userIdGift')
|
||||
const userPhone = uni.getStorageSync('userPhoneGift')
|
||||
const details = this.questions.map(q => ({
|
||||
question_id: q.question_id,
|
||||
user_answer: q.answerList[this.answers[q.question_id]]?.answer_content || ''
|
||||
}))
|
||||
this.$u.api.submitQA({
|
||||
user_id: userId,
|
||||
user_phone: userPhone,
|
||||
wenjuan_id: 1003,
|
||||
use_time: elapsed,
|
||||
total_question_num: this.questions.length,
|
||||
channel: 1,
|
||||
user_answer_details: details
|
||||
}).then(res => {
|
||||
if (res.code === 0) {
|
||||
uni.setStorageSync('resultDataGift', {
|
||||
...res.Data,
|
||||
use_time: elapsed,
|
||||
total_question_num: this.questions.length
|
||||
})
|
||||
uni.navigateTo({ url: '/pages/result/result' })
|
||||
} else {
|
||||
uni.showToast({ title: res.msg || '提交失败', icon: 'none' })
|
||||
}
|
||||
}).catch(() => {
|
||||
uni.showToast({ title: '网络异常', icon: 'none' })
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: #7CC6EB;
|
||||
}
|
||||
|
||||
.content {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100vh;
|
||||
height: 100dvh;
|
||||
}
|
||||
|
||||
.page-body {
|
||||
flex: 1;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.quiz-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20rpx;
|
||||
padding: 16rpx 24rpx;
|
||||
background: #71BCFB66;
|
||||
border-radius: 12rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.quiz-scroll {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.timer-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10rpx;
|
||||
}
|
||||
|
||||
.timer-label {
|
||||
font-size: 24rpx;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
|
||||
.timer {
|
||||
font-size: 28rpx;
|
||||
color: #fff;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.answered-count {
|
||||
font-size: 24rpx;
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
}
|
||||
|
||||
.question-item {
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
border-radius: 20rpx;
|
||||
padding: 32rpx 28rpx;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.q-header {
|
||||
display: flex;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.q-index {
|
||||
width: 44rpx;
|
||||
height: 44rpx;
|
||||
line-height: 44rpx;
|
||||
text-align: center;
|
||||
background: #FD5401;
|
||||
color: #fff;
|
||||
border-radius: 50%;
|
||||
font-size: 24rpx;
|
||||
font-weight: 600;
|
||||
flex-shrink: 0;
|
||||
margin-right: 16rpx;
|
||||
margin-top: 4rpx;
|
||||
}
|
||||
|
||||
.q-content {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
line-height: 1.6;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.options {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 14rpx;
|
||||
}
|
||||
|
||||
.option {
|
||||
padding: 22rpx 20rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border: 2rpx solid #eee;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
|
||||
.option.selected {
|
||||
border-color: #FD5401;
|
||||
background: rgba(253, 84, 1, 0.05);
|
||||
}
|
||||
|
||||
.option-radio {
|
||||
width: 36rpx;
|
||||
height: 36rpx;
|
||||
border-radius: 50%;
|
||||
border: 3rpx solid #CCC;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-right: 16rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.option-radio.checked {
|
||||
border-color: #FD5401;
|
||||
}
|
||||
|
||||
.radio-dot {
|
||||
width: 20rpx;
|
||||
height: 20rpx;
|
||||
border-radius: 50%;
|
||||
background: #FD5401;
|
||||
}
|
||||
|
||||
.option-text {
|
||||
font-size: 27rpx;
|
||||
color: #333;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.tips {
|
||||
background: rgba(255, 247, 237, 0.95);
|
||||
border-radius: 12rpx;
|
||||
padding: 20rpx;
|
||||
margin-top: 16rpx;
|
||||
border-left: 6rpx solid #FD5401;
|
||||
}
|
||||
|
||||
.tips-label {
|
||||
font-size: 24rpx;
|
||||
font-weight: 600;
|
||||
color: #FD5401;
|
||||
display: block;
|
||||
margin-bottom: 6rpx;
|
||||
}
|
||||
|
||||
.tips-text {
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.submit-btn {
|
||||
width: 100%;
|
||||
height: 88rpx;
|
||||
line-height: 88rpx;
|
||||
background: linear-gradient(135deg, #FD5401, #FF7A3D);
|
||||
color: #fff;
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
border: none;
|
||||
border-radius: 44rpx;
|
||||
margin: 10rpx 0 40rpx;
|
||||
box-shadow: 0 4rpx 16rpx rgba(253, 84, 1, 0.3);
|
||||
}
|
||||
|
||||
.loading-box {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.loading-text {
|
||||
font-size: 28rpx;
|
||||
color: #fff;
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
|
||||
.error-text {
|
||||
font-size: 28rpx;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.retry-btn {
|
||||
margin-top: 30rpx;
|
||||
width: 240rpx;
|
||||
height: 72rpx;
|
||||
line-height: 72rpx;
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
color: #FD5401;
|
||||
border: none;
|
||||
border-radius: 36rpx;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,329 @@
|
||||
<template>
|
||||
<view>
|
||||
<image src="https://aliyunoss.hn12301.net/learnlaw/gift_bj1_1.jpg" mode="widthFix"
|
||||
style="width: 750rpx;position: absolute;top: 0rpx;"></image>
|
||||
<image src="https://aliyunoss.hn12301.net/learnlaw/gift_dtcj1.png" @tap="goRegister"
|
||||
style="width: 180rpx;position: absolute;top:1920rpx;left: 165rpx;" mode="widthFix"></image>
|
||||
|
||||
<view style="width: 630rpx;height: 200rpx;position: absolute;top: 635rpx;left: 60rpx;">
|
||||
<view style="display: flex;align-items: center;width: 630rpx;justify-content: space-evenly;font-weight: bold;color:#503318;"><view class="tag"></view> {{ fiveStar ? '本轮答题赢好礼达成' : '本轮答题赢好礼未达成' }} <view class="tag1"></view></view>
|
||||
<view style="display: flex;align-items: center;width: 630rpx;justify-content: space-evenly;">
|
||||
<image :src="item<6 && fiveStar?'https://aliyunoss.hn12301.net/learnlaw/gift_yzg.png':'https://aliyunoss.hn12301.net/learnlaw/gift_mzg.png' " style="width: 120rpx;height: 120rpx;" v-for="item in 5" :key="item"></image>
|
||||
</view>
|
||||
|
||||
<view style="width: 630rpx;display: flex;align-items: center;justify-content: center;margin-top: -10rpx;font-size: 24rpx;color: #503318;" @tap="goRegister">{{ subTitle }}</view>
|
||||
</view>
|
||||
<image src="https://aliyunoss.hn12301.net/learnlaw/gift_ftxx1.png" @tap="goStudy"
|
||||
style="width: 180rpx;position: absolute;top:1920rpx;right:45rpx;" mode="widthFix"></image>
|
||||
<view class="rules-btn" @tap="goRules">
|
||||
<text class="rules-btn-text">活动规则</text>
|
||||
</view>
|
||||
|
||||
<image src="https://aliyunoss.hn12301.net/learnlaw/gift_ckjpxq1.png" @tap="toPrize()"
|
||||
style="width: 200rpx;position: absolute;top:1740rpx;right:275rpx;" mode="widthFix"></image>
|
||||
<u-tabbar :list="tabbarList" :hideTabBar="true" activeColor="#E88300" inactiveColor="#606060" :borderTop="false"
|
||||
height="120rpx" iconSize="48"></u-tabbar>
|
||||
<view class="blocked-mask" v-if="blocked">
|
||||
<text class="blocked-tip">{{ blockTip }}</text>
|
||||
<text class="blocked-sub">本活动仅支持手机微信访问</text>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const APP_ID = 'wx71c218bd9ff0e2da'
|
||||
const SCOPE = 'snsapi_base'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
fiveStar: false,
|
||||
registered: false,
|
||||
lvShow:false,
|
||||
blocked: false,
|
||||
blockTip: '',
|
||||
tabbarList: [{
|
||||
pagePath: "/pages/index/index",
|
||||
iconPath: "/static/shouye.png",
|
||||
selectedIconPath: "/static/shouye_select.png",
|
||||
text: "首页"
|
||||
},
|
||||
{
|
||||
pagePath: "/pages/records/records",
|
||||
iconPath: "/static/zhongjiangjilu.png",
|
||||
selectedIconPath: "/static/zhongjiangjilu_select.png",
|
||||
text: "中奖记录"
|
||||
},
|
||||
{
|
||||
pagePath: "/pages/profile/profile",
|
||||
iconPath: "/static/wode.png",
|
||||
selectedIconPath: "/static/wode_select.png",
|
||||
text: "我的"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
subTitle() {
|
||||
if (!this.registered) {
|
||||
return '您未注册,点击参与挑战去注册'
|
||||
}
|
||||
return this.fiveStar ? '本轮您已进入抽奖池' : '本轮您未进入抽奖池,坚持答题参与抽奖'
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
if (new Date().getTime() < new Date('2026/08/29 10:00:00')) {
|
||||
this.lvShow = true
|
||||
uni.redirectTo({
|
||||
url:'/pages/jqqd/jqqd'
|
||||
})
|
||||
}
|
||||
this.initLogin()
|
||||
},
|
||||
onShow() {
|
||||
if (this.blocked) return
|
||||
const openId = uni.getStorageSync('openIdGift')
|
||||
const isRegisteredGift = uni.getStorageSync('isRegisteredGift')
|
||||
const userId = uni.getStorageSync('userIdGift')
|
||||
this.registered = !!isRegisteredGift
|
||||
if (openId && (!isRegisteredGift || !userId)) {
|
||||
this.loginWithOpenId(openId)
|
||||
}
|
||||
if (isRegisteredGift && userId) {
|
||||
this.fetchUserResult()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
fetchUserResult() {
|
||||
const userId = uni.getStorageSync('userIdGift')
|
||||
if (!userId) return
|
||||
this.$u.api.getUserResult({ wenjuanId: 1003, userId }).then(res => {
|
||||
if (res.code !== 0 || !res.Data) return
|
||||
this.fiveStar = Number(res.Data.correct_question_num) === 5
|
||||
}).catch(err => {
|
||||
console.error('获取答题结果失败', err)
|
||||
})
|
||||
},
|
||||
initLogin() {
|
||||
if (!this.isWechatBrowser()) {
|
||||
this.block('请在微信中打开')
|
||||
return
|
||||
}
|
||||
if (this.isPcWechat()) {
|
||||
this.block('请使用手机微信打开')
|
||||
return
|
||||
}
|
||||
let openId = uni.getStorageSync('openIdGift')
|
||||
if (openId) {
|
||||
this.loginWithOpenId(openId)
|
||||
return
|
||||
}
|
||||
const code = this.getCodeFromUrl()
|
||||
if (code) {
|
||||
this.exchangeOpenId(code)
|
||||
} else {
|
||||
this.wechatAuth()
|
||||
}
|
||||
},
|
||||
block(tip) {
|
||||
this.blocked = true
|
||||
this.blockTip = tip
|
||||
},
|
||||
isWechatBrowser() {
|
||||
return /MicroMessenger/i.test(navigator.userAgent)
|
||||
},
|
||||
isPcWechat() {
|
||||
return /MicroMessenger/i.test(navigator.userAgent) && /WindowsWechat|MacWechat/i.test(navigator.userAgent)
|
||||
},
|
||||
getCodeFromUrl() {
|
||||
const match = window.location.href.match(/[?&]code=([^&#]+)/)
|
||||
return match ? match[1] : null
|
||||
},
|
||||
cleanUrlCode() {
|
||||
const cleanUrl = window.location.href.replace(/[?&]code=[^&#]*(&|#|$)/, (m, p1) => p1 === '&' ? '?' : (
|
||||
p1 === '#' ? '#' : ''))
|
||||
window.history.replaceState({}, '', cleanUrl)
|
||||
},
|
||||
wechatAuth() {
|
||||
const redirectUri = encodeURIComponent(window.location.href.split('?')[0].split('#')[0])
|
||||
const url =
|
||||
`https://open.weixin.qq.com/connect/oauth2/authorize?appid=${APP_ID}&redirect_uri=${redirectUri}&response_type=code&scope=${SCOPE}&state=STATE#wechat_redirect`
|
||||
window.location.href = url
|
||||
},
|
||||
exchangeOpenId(code) {
|
||||
this.$u.api.getWxOpenId(code).then(res => {
|
||||
if (res.code !== 0 || !res.Data || !res.Data.openid) return
|
||||
const openId = res.Data.openid
|
||||
uni.setStorageSync('openIdGift', openId)
|
||||
this.cleanUrlCode()
|
||||
return this.$u.api.wxOpenidLogin({ wenjuan_id: 1003, open_id: openId })
|
||||
}).then(loginRes => {
|
||||
if (loginRes && loginRes.code === 0 && loginRes.Data && loginRes.Data.user_name && loginRes.Data.user_phone) {
|
||||
uni.setStorageSync('isRegisteredGift', true)
|
||||
uni.setStorageSync('userIdGift', loginRes.Data.user_id || loginRes.Data.uesr_id)
|
||||
uni.setStorageSync('userNameGift', loginRes.Data.user_name)
|
||||
uni.setStorageSync('userPhoneGift', loginRes.Data.user_phone)
|
||||
this.registered = true
|
||||
this.fetchUserResult()
|
||||
} else if (loginRes && !loginRes.Data) {
|
||||
uni.setStorageSync('isRegisteredGift', false)
|
||||
this.registered = false
|
||||
}
|
||||
}).catch(err => {
|
||||
console.error('请求失败', err)
|
||||
})
|
||||
},
|
||||
loginWithOpenId(openId) {
|
||||
return this.$u.api.wxOpenidLogin({ wenjuan_id: 1003, open_id: openId }).then(loginRes => {
|
||||
if (!loginRes.Data) {
|
||||
uni.setStorageSync('isRegisteredGift', false)
|
||||
this.registered = false
|
||||
return
|
||||
}
|
||||
if (loginRes.code === 0 && loginRes.Data?.user_name && loginRes.Data?.user_phone) {
|
||||
uni.setStorageSync('isRegisteredGift', true)
|
||||
uni.setStorageSync('userIdGift', loginRes.Data.user_id || loginRes.Data.uesr_id)
|
||||
uni.setStorageSync('userNameGift', loginRes.Data.user_name)
|
||||
uni.setStorageSync('userPhoneGift', loginRes.Data.user_phone)
|
||||
this.registered = true
|
||||
this.fetchUserResult()
|
||||
}
|
||||
}).catch(err => {
|
||||
console.error('登录请求失败', err)
|
||||
})
|
||||
},
|
||||
toPrize() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/prize/prize'
|
||||
})
|
||||
},
|
||||
goStudy() {
|
||||
uni.navigateTo({ url: '/pages/study/preview' })
|
||||
},
|
||||
goRules() {
|
||||
uni.navigateTo({ url: '/pages/rules/rules' })
|
||||
},
|
||||
goPrize() {
|
||||
uni.navigateTo({ url: '/pages/prize/prize' })
|
||||
},
|
||||
goRegister() {
|
||||
if (uni.getStorageSync('isRegisteredGift')) {
|
||||
if (uni.getStorageSync('userIdGift') && uni.getStorageSync('userPhoneGift')) {
|
||||
uni.navigateTo({ url: '/pages/answer/answer' })
|
||||
return
|
||||
}
|
||||
uni.showLoading({ title: '加载中...' })
|
||||
this.loginWithOpenId(uni.getStorageSync('openIdGift')).then(() => {
|
||||
uni.hideLoading()
|
||||
if (uni.getStorageSync('userIdGift')) {
|
||||
uni.navigateTo({ url: '/pages/answer/answer' })
|
||||
} else {
|
||||
uni.showToast({ title: '用户信息获取失败,请重试', icon: 'none' })
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
uni.navigateTo({ url: '/pages/register/register' })
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: #7CC6EB;
|
||||
}
|
||||
|
||||
|
||||
.page-body {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.blocked-mask {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 999;
|
||||
background-color: #7CC6EB;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.blocked-tip {
|
||||
font-size: 36rpx;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.blocked-sub {
|
||||
font-size: 26rpx;
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
margin-top: 16rpx;
|
||||
}
|
||||
|
||||
.tag {
|
||||
width: 48rpx;
|
||||
height: 6rpx;
|
||||
border-radius: 3rpx;
|
||||
background: rgba(80, 51, 24, 0.45);
|
||||
}
|
||||
|
||||
.tag1 {
|
||||
width: 48rpx;
|
||||
height: 6rpx;
|
||||
border-radius: 3rpx;
|
||||
background: rgba(80, 51, 24, 0.45);
|
||||
}
|
||||
|
||||
.rules-btn {
|
||||
position: absolute;
|
||||
top: 950rpx;
|
||||
right: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 60rpx;
|
||||
padding: 0 26rpx;
|
||||
background: linear-gradient(135deg, #FFC24D, #FF8A3D);
|
||||
border-radius: 30rpx 0 0 30rpx;
|
||||
box-shadow: 0 4rpx 14rpx rgba(255, 138, 61, 0.45);
|
||||
}
|
||||
|
||||
.rules-btn:active {
|
||||
opacity: 0.85;
|
||||
}
|
||||
|
||||
.rules-btn-text {
|
||||
font-size: 24rpx;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
letter-spacing: 2rpx;
|
||||
}
|
||||
|
||||
::v-deep .u-tabbar__content {
|
||||
background: linear-gradient(to bottom, #FAFFC7, #B2FFC9) !important;
|
||||
}
|
||||
|
||||
::v-deep .u-tabbar__content__item {
|
||||
background: linear-gradient(to bottom, #FAFFC7, #B2FFC9) !important;
|
||||
}
|
||||
|
||||
::v-deep .u-tabbar {
|
||||
.u-border-top {
|
||||
border-top: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .u-icon__img {
|
||||
object-fit: contain !important;
|
||||
}
|
||||
|
||||
::v-deep .u-tabbar__content__item {
|
||||
padding: 16rpx 0 !important;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,22 @@
|
||||
<template>
|
||||
<view>
|
||||
<image src="https://aliyunoss.hn12301.net/learnlaw/gift_jqqd.jpg" style="width: 750rpx;" mode="widthFix"></image>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,189 @@
|
||||
<template>
|
||||
<view class="content">
|
||||
<view class="page-header">
|
||||
<text class="header-back" @tap="goBack">‹</text>
|
||||
<text class="header-title">用户隐私协议</text>
|
||||
</view>
|
||||
<scroll-view scroll-y class="doc-scroll">
|
||||
<view class="doc-card">
|
||||
<view class="doc-title">用户隐私协议</view>
|
||||
<text class="doc-meta">主办方:湖南一二三零一文化旅游服务有限公司</text>
|
||||
<text class="doc-meta">生效日期:自发布之日起</text>
|
||||
|
||||
<view class="sec">
|
||||
<text class="sec-title">一、适用范围</text>
|
||||
<text class="sec-text">本协议适用于"你学法我有礼——自然资源专场"普法答题抽奖活动(以下简称"本活动")过程中我们对您个人信息的收集、使用与保护。您勾选同意本协议即表示您已阅读、理解并同意本协议全部内容。</text>
|
||||
</view>
|
||||
<view class="sec">
|
||||
<text class="sec-title">二、我们收集的信息</text>
|
||||
<text class="sec-text">1. 注册信息:姓名、手机号码,用于活动参与资格确认与实名核验,短信验证码用于验证手机归属;</text>
|
||||
<text class="sec-text">2. 微信授权信息:openid,用于关联您的身份与本活动答题、中奖记录;</text>
|
||||
<text class="sec-text">3. 答题与积分数据:答题记录、对错结果、用时及积分,用于成绩结算、排名与抽奖;</text>
|
||||
<text class="sec-text">4. 中奖及兑奖信息:中奖记录;兑奖时需填写身份证号码,仅用于核验兑奖资格及奖品发放。</text>
|
||||
</view>
|
||||
<view class="sec">
|
||||
<text class="sec-title">三、信息的使用</text>
|
||||
<text class="sec-text">1. 提供答题、积分计算、排名及开奖抽奖服务;</text>
|
||||
<text class="sec-text">2. 验证用户身份及实名信息真实性,保障活动公平,防范刷量、冒领;</text>
|
||||
<text class="sec-text">3. 完成兑奖核验,并在中奖时与您联系;</text>
|
||||
<text class="sec-text">4. 满足法律法规及主管部门的监管要求。</text>
|
||||
</view>
|
||||
<view class="sec">
|
||||
<text class="sec-title">四、信息的存储与保护</text>
|
||||
<text class="sec-text">1. 您的个人信息存储于活动服务器,并采取加密传输、访问控制等安全措施;</text>
|
||||
<text class="sec-text">2. 我们不会出售您的个人信息,亦不会向与本活动无关的第三方提供;除法律法规明确要求或司法、行政机关依法要求外,任何共享均经审慎评估;</text>
|
||||
<text class="sec-text">3. 活动结束后,相关数据将依法律规定予以保留或删除。</text>
|
||||
</view>
|
||||
<view class="sec">
|
||||
<text class="sec-title">五、信息的公示</text>
|
||||
<text class="sec-text">为保障抽奖活动公开透明,中奖名单、积分排行等信息将依活动监管要求进行公示,公示内容将对姓名、手机号码等个人信息作脱敏处理。</text>
|
||||
</view>
|
||||
<view class="sec">
|
||||
<text class="sec-title">六、您的权利</text>
|
||||
<text class="sec-text">您可通过本协议所列联系方式向我们申请查询、更正、删除您的个人信息,或撤回您的同意。撤回同意不影响撤回前基于同意已进行的信息处理,但可能导致您无法继续参与本活动。</text>
|
||||
</view>
|
||||
<view class="sec">
|
||||
<text class="sec-title">七、未成年人保护</text>
|
||||
<text class="sec-text">本活动面向具备完全民事行为能力的成年人。未满十八周岁的未成年人请勿在本活动中提交个人信息,如需参与应取得监护人同意并在监护人陪同下进行。</text>
|
||||
</view>
|
||||
<view class="sec">
|
||||
<text class="sec-title">八、协议更新</text>
|
||||
<text class="sec-text">我们可能根据活动安排及法律法规变化适时更新本协议,更新后的协议将在活动页面公示后生效。若您继续参与活动,即表示您接受更新后的协议。</text>
|
||||
</view>
|
||||
<view class="sec">
|
||||
<text class="sec-title">九、联系方式</text>
|
||||
<text class="sec-text">如您对本协议或本活动个人信息保护事宜有任何疑问、意见或投诉,请通过以下方式联系我们:</text>
|
||||
<text class="sec-text">主办方:湖南一二三零一文化旅游服务有限公司</text>
|
||||
<text class="sec-text">联系电话:0731-88912301</text>
|
||||
</view>
|
||||
<view style="height: 40rpx;"></view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<view class="page-footer">
|
||||
<button class="agree-btn" @tap="agreeAndBack">已阅读并同意</button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
methods: {
|
||||
goBack() {
|
||||
uni.navigateBack()
|
||||
},
|
||||
agreeAndBack() {
|
||||
const pages = getCurrentPages()
|
||||
const prev = pages[pages.length - 2]
|
||||
if (prev && prev.$vm) prev.$vm.agreed = true
|
||||
uni.navigateBack()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: #F5F5F5;
|
||||
}
|
||||
|
||||
.content {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100vh;
|
||||
height: 100dvh;
|
||||
}
|
||||
|
||||
.page-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 20rpx 30rpx;
|
||||
background: linear-gradient(135deg, #FD5401, #FF7A3D);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.header-back {
|
||||
font-size: 48rpx;
|
||||
color: #fff;
|
||||
line-height: 1;
|
||||
margin-right: 16rpx;
|
||||
padding: 0 10rpx;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.doc-scroll {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
padding-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.doc-card {
|
||||
background: #fff;
|
||||
margin: 24rpx;
|
||||
border-radius: 20rpx;
|
||||
padding: 36rpx 30rpx;
|
||||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.doc-title {
|
||||
font-size: 36rpx;
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
text-align: center;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.doc-meta {
|
||||
display: block;
|
||||
font-size: 22rpx;
|
||||
color: #999;
|
||||
text-align: center;
|
||||
line-height: 1.8;
|
||||
}
|
||||
|
||||
.sec {
|
||||
margin-top: 30rpx;
|
||||
}
|
||||
|
||||
.sec-title {
|
||||
display: block;
|
||||
font-size: 28rpx;
|
||||
font-weight: 700;
|
||||
color: #FD5401;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.sec-text {
|
||||
display: block;
|
||||
font-size: 26rpx;
|
||||
color: #555;
|
||||
line-height: 1.7;
|
||||
margin-bottom: 6rpx;
|
||||
}
|
||||
|
||||
.page-footer {
|
||||
flex-shrink: 0;
|
||||
padding: 20rpx 30rpx 40rpx;
|
||||
background: #fff;
|
||||
border-top: 1rpx solid #f0f0f0;
|
||||
}
|
||||
|
||||
.agree-btn {
|
||||
width: 100%;
|
||||
height: 88rpx;
|
||||
line-height: 88rpx;
|
||||
background: linear-gradient(135deg, #FD5401, #FF7A3D);
|
||||
color: #fff;
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
border: none;
|
||||
border-radius: 44rpx;
|
||||
box-shadow: 0 4rpx 16rpx rgba(253, 84, 1, 0.3);
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,28 @@
|
||||
<template>
|
||||
<view>
|
||||
<image src="https://aliyunoss.hn12301.net/learnlaw/gift_jp.jpg" style="width: 750rpx;" mode="widthFix"></image>
|
||||
<image src="https://aliyunoss.hn12301.net/learnlaw/gift_jp_an.png" style="width: 200rpx;position: absolute;left: 275rpx;top: 1600rpx;" mode="widthFix" @click="toIndex"></image>
|
||||
<!-- <view style="width: 240rpx;height: 80rpx;position: absolute;top:3130rpx;left: 255rpx;" @click="toIndex()"></view> -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
|
||||
},
|
||||
methods:{
|
||||
toIndex(){
|
||||
uni.navigateBack()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,270 @@
|
||||
<template>
|
||||
<view class="content">
|
||||
<image src="https://aliyunoss.hn12301.net/learnlaw/gift_zt_bj.jpg" mode="scaleToFill" :style="{ width: '750rpx', height: bgHeight + 'px', position: 'absolute', top: 0, left: 0, zIndex: 0 }"></image>
|
||||
<view class="page-body">
|
||||
<view class="login-box" v-if="!isLoggedIn">
|
||||
<text class="login-tip">注册后享受更多功能</text>
|
||||
<button class="login-btn" @tap="goRegister">立即注册</button>
|
||||
</view>
|
||||
<template v-if="isLoggedIn">
|
||||
<view class="user-card">
|
||||
<view class="user-avatar">
|
||||
<text class="avatar-text">{{ userName.charAt(0) }}</text>
|
||||
</view>
|
||||
<view class="user-info">
|
||||
<text class="user-name">{{ userName }}</text>
|
||||
<text class="user-phone">{{ maskedPhone }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="menu-list">
|
||||
<view class="menu-item" @tap="goMyPrizes">
|
||||
<view class="menu-icon menu-icon-prize">
|
||||
<text>🎁</text>
|
||||
</view>
|
||||
<text class="menu-text">我的奖品</text>
|
||||
<text class="menu-arrow">›</text>
|
||||
</view>
|
||||
<view class="menu-item" @tap="goAnswerRecords">
|
||||
<view class="menu-icon menu-icon-points">
|
||||
<text>📊</text>
|
||||
</view>
|
||||
<text class="menu-text">答题记录</text>
|
||||
<text class="menu-arrow">›</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
<u-tabbar
|
||||
:list="tabbarList"
|
||||
:hideTabBar="true"
|
||||
activeColor="#FD5401"
|
||||
inactiveColor="#5D533D"
|
||||
:borderTop="false"
|
||||
height="120rpx"
|
||||
iconSize="48"
|
||||
></u-tabbar>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
bgHeight: 0,
|
||||
tabbarList: [
|
||||
{ pagePath: "/pages/index/index", iconPath: "/static/shouye.png", selectedIconPath: "/static/shouye_select.png", text: "首页" },
|
||||
{ pagePath: "/pages/records/records", iconPath: "/static/zhongjiangjilu.png", selectedIconPath: "/static/zhongjiangjilu_select.png", text: "中奖记录" },
|
||||
{ pagePath: "/pages/profile/profile", iconPath: "/static/wode.png", selectedIconPath: "/static/wode_select.png", text: "我的" }
|
||||
],
|
||||
isLoggedIn: false,
|
||||
userName: '',
|
||||
userPhone: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
maskedPhone() {
|
||||
const p = this.userPhone
|
||||
if (!p || p.length < 7) return p
|
||||
return p.slice(0, 3) + '****' + p.slice(-4)
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
const sys = uni.getSystemInfoSync()
|
||||
const tabbarHeight = sys.windowWidth / 750 * 120
|
||||
this.bgHeight = sys.windowHeight - tabbarHeight
|
||||
},
|
||||
onShow() {
|
||||
this.checkLogin()
|
||||
},
|
||||
methods: {
|
||||
checkLogin() {
|
||||
const userId = uni.getStorageSync('userIdGift')
|
||||
if (userId) {
|
||||
this.isLoggedIn = true
|
||||
this.userName = uni.getStorageSync('userNameGift') || ''
|
||||
this.userPhone = uni.getStorageSync('userPhoneGift') || ''
|
||||
} else {
|
||||
this.isLoggedIn = false
|
||||
}
|
||||
},
|
||||
goRegister() {
|
||||
uni.navigateTo({ url: '/pages/register/register' })
|
||||
},
|
||||
goMyPrizes() {
|
||||
const phone = uni.getStorageSync('userPhoneGift') || ''
|
||||
window.location.href = 'https://goldnar.hntgov.net/cardholder/index.html#/?phone=' + phone
|
||||
},
|
||||
goAnswerRecords() {
|
||||
uni.navigateTo({ url: '/pages/answer-record/answer-record' })
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: #6EC5E3;
|
||||
}
|
||||
|
||||
.content {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
}
|
||||
|
||||
.page-body {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
flex: 1;
|
||||
padding: 160rpx 30rpx 20rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.login-box {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.login-tip {
|
||||
font-size: 28rpx;
|
||||
color: rgba(255,255,255,0.85);
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
.login-btn {
|
||||
width: 400rpx;
|
||||
height: 80rpx;
|
||||
line-height: 80rpx;
|
||||
background: linear-gradient(135deg, #FD5401, #FF7A3D);
|
||||
color: #fff;
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
border: none;
|
||||
border-radius: 40rpx;
|
||||
box-shadow: 0 4rpx 16rpx rgba(253,84,1,0.3);
|
||||
}
|
||||
|
||||
.user-card {
|
||||
background: rgba(255,255,255,0.95);
|
||||
border-radius: 20rpx;
|
||||
padding: 36rpx 30rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 24rpx;
|
||||
box-shadow: 0 4rpx 20rpx rgba(0,0,0,0.06);
|
||||
}
|
||||
|
||||
.user-avatar {
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(135deg, #FD5401, #FF7A3D);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
margin-right: 24rpx;
|
||||
}
|
||||
|
||||
.avatar-text {
|
||||
font-size: 32rpx;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.user-info {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.user-name {
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.user-phone {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
margin-top: 6rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.menu-list {
|
||||
background: rgba(255,255,255,0.95);
|
||||
border-radius: 20rpx;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 4rpx 20rpx rgba(0,0,0,0.06);
|
||||
}
|
||||
|
||||
.menu-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 30rpx 28rpx;
|
||||
border-bottom: 1rpx solid #f0f0f0;
|
||||
}
|
||||
|
||||
.menu-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.menu-icon {
|
||||
width: 52rpx;
|
||||
height: 52rpx;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
margin-right: 20rpx;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.menu-icon-prize {
|
||||
background: #fff7e6;
|
||||
}
|
||||
|
||||
.menu-icon-points {
|
||||
background: #e6f7ff;
|
||||
}
|
||||
|
||||
.menu-text {
|
||||
flex: 1;
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.menu-arrow {
|
||||
font-size: 36rpx;
|
||||
color: #ccc;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
::v-deep .u-tabbar__content {
|
||||
background: linear-gradient(to bottom, #FAFFC7, #B2FFC9) !important;
|
||||
}
|
||||
|
||||
::v-deep .u-tabbar__content__item {
|
||||
background: linear-gradient(to bottom, #FAFFC7, #B2FFC9) !important;
|
||||
}
|
||||
|
||||
::v-deep .u-tabbar {
|
||||
.u-border-top {
|
||||
border-top: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .u-icon__img {
|
||||
object-fit: contain !important;
|
||||
}
|
||||
|
||||
::v-deep .u-tabbar__content__item {
|
||||
padding: 16rpx 0 !important;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,391 @@
|
||||
<template>
|
||||
<view class="content">
|
||||
<view class="page-body">
|
||||
<image src="https://aliyunoss.hn12301.net/learnlaw/gift_zt_bj.jpg" mode="widthFix" style="width:750rpx;position:absolute;top:0;left:0;z-index:-1;"></image>
|
||||
<view class="login-box" v-if="!isLoggedIn">
|
||||
<text class="login-tip">注册后可查看排行榜</text>
|
||||
<button class="login-btn" @tap="goRegister">立即注册</button>
|
||||
</view>
|
||||
<template v-if="isLoggedIn">
|
||||
<view class="header">
|
||||
<view class="header-icon"><text>🏆</text></view>
|
||||
<text class="header-title">排行榜</text>
|
||||
<view class="header-line"></view>
|
||||
<view class="my-rank" v-if="myRank">
|
||||
<text class="my-rank-label">我的排名</text>
|
||||
<text class="my-rank-value">第 {{ myRank }} 名</text>
|
||||
<text class="my-rank-stats">{{ myScore }}分 · {{ myTime }}s</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="rank-list" v-if="list.length > 0">
|
||||
<view class="rank-item" v-for="(item, i) in list" :key="i">
|
||||
<view class="rank-index" :class="'rank-' + (item.index || i + 1)">
|
||||
<text v-if="(item.index || i + 1) <= 3">
|
||||
<image :src="'https://aliyunoss.hn12301.net/sd/rank' + (i + 1) + '.png'" mode="widthFix" style="width:36rpx;"></image>
|
||||
</text>
|
||||
<text v-else class="rank-num">{{ item.index }}</text>
|
||||
</view>
|
||||
<view class="rank-info">
|
||||
<text class="rank-name">{{ item.user_name }}</text>
|
||||
<text class="rank-phone">{{ item.user_phone }}</text>
|
||||
</view>
|
||||
<view class="rank-stats">
|
||||
<text class="rank-time">{{ item.total_time }}s</text>
|
||||
<text class="rank-score">{{ item.total_score }}分</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="load-more" v-if="hasMore">
|
||||
<u-loading mode="circle" size="28"></u-loading>
|
||||
<text class="load-text">加载更多...</text>
|
||||
</view>
|
||||
<view class="no-more" v-if="!hasMore && list.length > 0">
|
||||
<text class="no-more-text">— 没有更多了 —</text>
|
||||
</view>
|
||||
<view class="empty-box" v-if="list.length === 0">
|
||||
<text class="empty-icon">🏆</text>
|
||||
<text class="empty-text">暂无排行榜数据</text>
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
<u-tabbar
|
||||
:list="tabbarList"
|
||||
:hideTabBar="true"
|
||||
activeColor="#FD5401"
|
||||
inactiveColor="#5D533D"
|
||||
:borderTop="false"
|
||||
height="120rpx"
|
||||
iconSize="48"
|
||||
></u-tabbar>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
tabbarList: [
|
||||
{ pagePath: "/pages/index/index", iconPath: "/static/shouye.png", selectedIconPath: "/static/shouye_select.png", text: "首页" },
|
||||
{ pagePath: "/pages/ranking/ranking", iconPath: "/static/paihangbang.png", selectedIconPath: "/static/paihangbang_select.png", text: "排行榜" },
|
||||
{ pagePath: "/pages/records/records", iconPath: "/static/zhongjiangjilu.png", selectedIconPath: "/static/zhongjiangjilu_select.png", text: "中将记录" },
|
||||
{ pagePath: "/pages/profile/profile", iconPath: "/static/wode.png", selectedIconPath: "/static/wode_select.png", text: "我的" }
|
||||
],
|
||||
isLoggedIn: false,
|
||||
list: [],
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
hasMore: true,
|
||||
loading: false,
|
||||
myRank: null,
|
||||
myScore: 0,
|
||||
myTime: 0
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
this.checkLogin()
|
||||
},
|
||||
onShow() {
|
||||
this.checkLogin()
|
||||
},
|
||||
methods: {
|
||||
checkLogin() {
|
||||
const userId = uni.getStorageSync('userIdGift')
|
||||
if (userId) {
|
||||
this.isLoggedIn = true
|
||||
this.pageNum = 1
|
||||
this.hasMore = true
|
||||
this.fetchList()
|
||||
} else {
|
||||
this.isLoggedIn = false
|
||||
}
|
||||
},
|
||||
goRegister() {
|
||||
uni.navigateTo({ url: '/pages/register/register' })
|
||||
},
|
||||
fetchList() {
|
||||
if (this.loading || !this.hasMore) return
|
||||
this.loading = true
|
||||
const userId = uni.getStorageSync('userIdGift')
|
||||
this.$u.api.getWenjuanPhb({
|
||||
user_id: userId,
|
||||
wenjuan_id: 1003,
|
||||
pageNum: this.pageNum,
|
||||
pageSize: this.pageSize
|
||||
}).then(res => {
|
||||
if (res.code === 0) {
|
||||
const data = res.Data
|
||||
if (this.pageNum === 1) {
|
||||
this.list = data.phb || []
|
||||
this.myRank = data.pm
|
||||
this.myScore = data.score || 0
|
||||
this.myTime = data.time || 0
|
||||
} else {
|
||||
this.list = this.list.concat(data.phb || [])
|
||||
}
|
||||
this.hasMore = (data.phb || []).length >= this.pageSize
|
||||
} else {
|
||||
uni.showToast({ title: res.msg || '加载失败', icon: 'none' })
|
||||
}
|
||||
}).catch(() => {
|
||||
uni.showToast({ title: '网络异常', icon: 'none' })
|
||||
}).finally(() => {
|
||||
this.loading = false
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: #B3E9F3;
|
||||
}
|
||||
|
||||
.content {
|
||||
position: relative;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.page-body {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
flex: 1;
|
||||
padding: 80rpx 30rpx 20rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.login-box {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.login-tip {
|
||||
font-size: 28rpx;
|
||||
color: rgba(255,255,255,0.85);
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
.login-btn {
|
||||
width: 400rpx;
|
||||
height: 80rpx;
|
||||
line-height: 80rpx;
|
||||
background: linear-gradient(135deg, #FD5401, #FF7A3D);
|
||||
color: #fff;
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
border: none;
|
||||
border-radius: 40rpx;
|
||||
box-shadow: 0 4rpx 16rpx rgba(253,84,1,0.3);
|
||||
}
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
.header-icon {
|
||||
font-size: 52rpx;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-size: 36rpx;
|
||||
font-weight: 800;
|
||||
color: #fff;
|
||||
text-shadow: 0 2rpx 8rpx rgba(0,0,0,0.15);
|
||||
letter-spacing: 4rpx;
|
||||
}
|
||||
|
||||
.header-line {
|
||||
width: 60rpx;
|
||||
height: 4rpx;
|
||||
background: rgba(255,255,255,0.5);
|
||||
border-radius: 2rpx;
|
||||
margin-top: 12rpx;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.my-rank {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 20rpx;
|
||||
background: rgba(255,255,255,0.2);
|
||||
border-radius: 16rpx;
|
||||
padding: 16rpx 28rpx;
|
||||
margin-top: 16rpx;
|
||||
}
|
||||
|
||||
.my-rank-label {
|
||||
font-size: 24rpx;
|
||||
color: rgba(255,255,255,0.8);
|
||||
}
|
||||
|
||||
.my-rank-value {
|
||||
font-size: 28rpx;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.my-rank-stats {
|
||||
font-size: 22rpx;
|
||||
color: rgba(255,255,255,0.65);
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.rank-list {
|
||||
background: rgba(255,255,255,0.95);
|
||||
border-radius: 20rpx;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 4rpx 20rpx rgba(0,0,0,0.06);
|
||||
}
|
||||
|
||||
.rank-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 28rpx 24rpx;
|
||||
border-bottom: 1rpx solid #f0f0f0;
|
||||
}
|
||||
|
||||
.rank-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.rank-index {
|
||||
width: 56rpx;
|
||||
height: 56rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
margin-right: 16rpx;
|
||||
border-radius: 50%;
|
||||
background: #f5f5f5;
|
||||
}
|
||||
|
||||
.rank-index.rank-1 {
|
||||
background: #fff7e6;
|
||||
}
|
||||
|
||||
.rank-index.rank-2 {
|
||||
background: #f0f0f0;
|
||||
}
|
||||
|
||||
.rank-index.rank-3 {
|
||||
background: #fef6e7;
|
||||
}
|
||||
|
||||
.rank-num {
|
||||
font-size: 24rpx;
|
||||
font-weight: 700;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.rank-info {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.rank-name {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.rank-phone {
|
||||
font-size: 22rpx;
|
||||
color: #bbb;
|
||||
margin-top: 4rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.rank-stats {
|
||||
text-align: right;
|
||||
flex-shrink: 0;
|
||||
margin-left: 16rpx;
|
||||
}
|
||||
|
||||
.rank-time {
|
||||
font-size: 22rpx;
|
||||
color: #999;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.rank-score {
|
||||
font-size: 30rpx;
|
||||
font-weight: 700;
|
||||
color: #FD5401;
|
||||
display: block;
|
||||
margin-top: 4rpx;
|
||||
}
|
||||
|
||||
.load-more {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 30rpx 0;
|
||||
gap: 10rpx;
|
||||
}
|
||||
|
||||
.load-text {
|
||||
font-size: 24rpx;
|
||||
color: rgba(255,255,255,0.7);
|
||||
}
|
||||
|
||||
.no-more {
|
||||
text-align: center;
|
||||
padding: 24rpx 0;
|
||||
}
|
||||
|
||||
.no-more-text {
|
||||
font-size: 22rpx;
|
||||
color: rgba(255,255,255,0.5);
|
||||
}
|
||||
|
||||
.empty-box {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 80rpx 0;
|
||||
}
|
||||
|
||||
.empty-icon {
|
||||
font-size: 80rpx;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
font-size: 26rpx;
|
||||
color: rgba(255,255,255,0.7);
|
||||
}
|
||||
|
||||
::v-deep .u-tabbar__content {
|
||||
background: linear-gradient(to bottom, #FAFFC7, #B2FFC9) !important;
|
||||
}
|
||||
|
||||
::v-deep .u-tabbar__content__item {
|
||||
background: linear-gradient(to bottom, #FAFFC7, #B2FFC9) !important;
|
||||
}
|
||||
|
||||
::v-deep .u-tabbar {
|
||||
.u-border-top {
|
||||
border-top: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .u-icon__img {
|
||||
object-fit: contain !important;
|
||||
}
|
||||
|
||||
::v-deep .u-tabbar__content__item {
|
||||
padding: 16rpx 0 !important;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,227 @@
|
||||
<template>
|
||||
<view class="content">
|
||||
<image src="https://aliyunoss.hn12301.net/learnlaw/gift_zt_bj.jpg" mode="widthFix" style="width:750rpx;position:absolute;top:0;left:0;z-index:-1;"></image>
|
||||
<view class="page-body">
|
||||
<view class="loading-box" v-if="detailList.length === 0 && !loadError">
|
||||
<u-loading mode="circle" size="40"></u-loading>
|
||||
<text class="loading-text">加载中...</text>
|
||||
</view>
|
||||
<view class="loading-box" v-if="loadError">
|
||||
<text class="error-text">{{ loadError }}</text>
|
||||
<button class="retry-btn" @tap="fetchDetail">重新加载</button>
|
||||
</view>
|
||||
<template v-if="detailList.length > 0">
|
||||
<view class="detail-item" v-for="(item, i) in detailList" :key="item.id">
|
||||
<view class="detail-index" :class="item.is_correct ? 'correct' : 'wrong'">
|
||||
<text class="detail-index-text">{{ i + 1 }}</text>
|
||||
</view>
|
||||
<view class="detail-body">
|
||||
<text class="detail-q">{{ item.tiku_question_content }}</text>
|
||||
<view class="detail-answer-row">
|
||||
<text class="detail-label">你的答案:</text>
|
||||
<text class="detail-value" :class="item.is_correct ? 'text-correct' : 'text-wrong'">{{ item.user_answer }}</text>
|
||||
</view>
|
||||
<view class="detail-answer-row" v-if="!item.is_correct">
|
||||
<text class="detail-label">正确答案:</text>
|
||||
<text class="detail-value text-correct-answer">{{ item.tiku_correct_answer }}</text>
|
||||
</view>
|
||||
<view class="tips" v-if="item.tips">
|
||||
<text class="tips-label">解析</text>
|
||||
<text class="tips-text">{{ item.tips }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
resultId: 0,
|
||||
detailList: [],
|
||||
loadError: ''
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
this.resultId = options.resultId
|
||||
this.fetchDetail()
|
||||
},
|
||||
methods: {
|
||||
fetchDetail() {
|
||||
this.loadError = ''
|
||||
this.$u.api.getUserHisResultDetail({
|
||||
resultId: this.resultId
|
||||
}).then(res => {
|
||||
if (res.code === 0 && Array.isArray(res.Data) && res.Data.length) {
|
||||
this.detailList = res.Data
|
||||
} else {
|
||||
this.loadError = res.msg || '数据异常'
|
||||
}
|
||||
}).catch(err => {
|
||||
console.error('获取答题详情失败', err)
|
||||
this.loadError = '网络请求失败'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: #7CC6EB;
|
||||
}
|
||||
|
||||
.content {
|
||||
position: relative;
|
||||
min-height: 100vh;
|
||||
min-height: 100dvh;
|
||||
}
|
||||
|
||||
.page-body {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
min-height: 100vh;
|
||||
min-height: 100dvh;
|
||||
padding: 40rpx 30rpx;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.detail-item {
|
||||
background: rgba(255,255,255,0.95);
|
||||
border-radius: 20rpx;
|
||||
padding: 28rpx;
|
||||
margin-bottom: 20rpx;
|
||||
display: flex;
|
||||
box-shadow: 0 2rpx 12rpx rgba(0,0,0,0.04);
|
||||
}
|
||||
|
||||
.detail-index {
|
||||
width: 44rpx;
|
||||
height: 44rpx;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
margin-right: 16rpx;
|
||||
margin-top: 2rpx;
|
||||
}
|
||||
|
||||
.detail-index.correct {
|
||||
background: linear-gradient(135deg, #52c41a, #73d13d);
|
||||
box-shadow: 0 2rpx 8rpx rgba(82,196,26,0.3);
|
||||
}
|
||||
|
||||
.detail-index.wrong {
|
||||
background: linear-gradient(135deg, #f5222d, #ff4d4f);
|
||||
box-shadow: 0 2rpx 8rpx rgba(245,34,45,0.3);
|
||||
}
|
||||
|
||||
.detail-index-text {
|
||||
font-size: 20rpx;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.detail-body {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.detail-q {
|
||||
font-size: 26rpx;
|
||||
color: #333;
|
||||
line-height: 1.5;
|
||||
display: block;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.detail-answer-row {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
margin-top: 4rpx;
|
||||
}
|
||||
|
||||
.detail-label {
|
||||
font-size: 22rpx;
|
||||
color: #999;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.detail-value {
|
||||
font-size: 24rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.text-correct {
|
||||
color: #52c41a;
|
||||
}
|
||||
|
||||
.text-wrong {
|
||||
color: #f5222d;
|
||||
}
|
||||
|
||||
.text-correct-answer {
|
||||
color: #52c41a;
|
||||
}
|
||||
|
||||
.tips {
|
||||
background: rgba(255, 247, 237, 0.95);
|
||||
border-radius: 12rpx;
|
||||
padding: 20rpx;
|
||||
margin-top: 16rpx;
|
||||
border-left: 6rpx solid #FD5401;
|
||||
}
|
||||
|
||||
.tips-label {
|
||||
font-size: 24rpx;
|
||||
font-weight: 600;
|
||||
color: #FD5401;
|
||||
display: block;
|
||||
margin-bottom: 6rpx;
|
||||
}
|
||||
|
||||
.tips-text {
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.loading-box {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.loading-text {
|
||||
font-size: 28rpx;
|
||||
color: #fff;
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
|
||||
.error-text {
|
||||
font-size: 28rpx;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.retry-btn {
|
||||
margin-top: 30rpx;
|
||||
width: 240rpx;
|
||||
height: 72rpx;
|
||||
line-height: 72rpx;
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
color: #FD5401;
|
||||
border: none;
|
||||
border-radius: 36rpx;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,504 @@
|
||||
<template>
|
||||
<view class="content">
|
||||
<view class="page-body">
|
||||
<image src="https://aliyunoss.hn12301.net/learnlaw/gift_zt_bj.jpg" mode="scaleToFill" :style="{ width: '750rpx', height: bgHeight + 'px', position: 'absolute', top: 0, left: 0, zIndex: -1 }"></image>
|
||||
<view class="login-box" v-if="!isLoggedIn">
|
||||
<text class="login-tip">注册后可查看中奖记录</text>
|
||||
<button class="login-btn" @tap="goRegister">立即注册</button>
|
||||
</view>
|
||||
<template v-if="isLoggedIn">
|
||||
<view class="header">
|
||||
<view class="header-icon"><text>🏆</text></view>
|
||||
<text class="header-title">中奖记录</text>
|
||||
<view class="header-line"></view>
|
||||
</view>
|
||||
<view class="record-list" v-if="list.length > 0">
|
||||
<view class="record-item" v-for="(item, i) in list" :key="i">
|
||||
<view class="record-icon">
|
||||
<text class="iconfont">🎁</text>
|
||||
</view>
|
||||
<view class="record-info">
|
||||
<text class="record-prize">{{ item.title }}</text>
|
||||
<text class="record-desc">{{ item.is_win_pc_desc }}</text>
|
||||
<text class="record-status">{{ item.status_desc }}</text>
|
||||
</view>
|
||||
<view class="record-right">
|
||||
<text class="record-time">{{ item.time }}</text>
|
||||
<view class="btn-row">
|
||||
<button class="winlist-btn" v-if="isEnded(item)" @tap="showWinList(item)">中奖名单</button>
|
||||
<button class="redeem-btn" v-if="item.is_win_pc == 1" @tap="redeem(item)">兑奖</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="empty-box" v-if="list.length === 0">
|
||||
<text class="empty-icon">🏆</text>
|
||||
<text class="empty-text">暂无中奖记录</text>
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
|
||||
<view class="modal-mask" v-if="showWinModal" @tap="closeWinModal"></view>
|
||||
<view class="modal win-modal" v-if="showWinModal">
|
||||
<view class="modal-header">
|
||||
<text class="modal-title">中奖名单</text>
|
||||
<text class="modal-close" @tap="closeWinModal">✕</text>
|
||||
</view>
|
||||
<view class="win-list">
|
||||
<view class="win-item" v-for="(w, wi) in winList" :key="wi">
|
||||
<view class="win-level" :class="'win-level-' + w.win_level">
|
||||
<text>{{ w.win_level_name }}</text>
|
||||
</view>
|
||||
<text class="win-name">{{ w.user_name }}</text>
|
||||
<text class="win-phone">{{ w.user_phone }}</text>
|
||||
</view>
|
||||
<view class="win-empty" v-if="winList.length === 0">
|
||||
<text>暂无中奖名单</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<u-tabbar
|
||||
:list="tabbarList"
|
||||
:hideTabBar="true"
|
||||
activeColor="#FD5401"
|
||||
inactiveColor="#5D533D"
|
||||
:borderTop="false"
|
||||
height="120rpx"
|
||||
iconSize="48"
|
||||
></u-tabbar>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
bgHeight: 0,
|
||||
tabbarList: [
|
||||
{ pagePath: "/pages/index/index", iconPath: "/static/shouye.png", selectedIconPath: "/static/shouye_select.png", text: "首页" },
|
||||
|
||||
{ pagePath: "/pages/records/records", iconPath: "/static/zhongjiangjilu.png", selectedIconPath: "/static/zhongjiangjilu_select.png", text: "中奖记录" },
|
||||
{ pagePath: "/pages/profile/profile", iconPath: "/static/wode.png", selectedIconPath: "/static/wode_select.png", text: "我的" }
|
||||
],
|
||||
isLoggedIn: false,
|
||||
list: [],
|
||||
showWinModal: false,
|
||||
winList: []
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
const sys = uni.getSystemInfoSync()
|
||||
const tabbarHeight = sys.windowWidth / 750 * 120
|
||||
this.bgHeight = sys.windowHeight - tabbarHeight
|
||||
},
|
||||
onShow() {
|
||||
this.checkLogin()
|
||||
},
|
||||
methods: {
|
||||
checkLogin() {
|
||||
const userId = uni.getStorageSync('userIdGift')
|
||||
if (userId) {
|
||||
this.isLoggedIn = true
|
||||
this.fetchList(userId)
|
||||
} else {
|
||||
this.isLoggedIn = false
|
||||
}
|
||||
},
|
||||
goRegister() {
|
||||
uni.navigateTo({ url: '/pages/register/register' })
|
||||
},
|
||||
fetchList(userId) {
|
||||
this.$u.api.getChouJiangResult({
|
||||
user_id: userId,
|
||||
wenjuan_id: 1003
|
||||
}).then(res => {
|
||||
if (res.code === 0) {
|
||||
const data = res.Data || {}
|
||||
this.list = data.list || data.records || data || []
|
||||
if (!Array.isArray(this.list)) this.list = []
|
||||
} else {
|
||||
uni.showToast({ title: res.msg || '加载失败', icon: 'none' })
|
||||
}
|
||||
}).catch(() => {
|
||||
uni.showToast({ title: '网络异常', icon: 'none' })
|
||||
})
|
||||
},
|
||||
isEnded(item) {
|
||||
return String(item.status_desc || '').indexOf('已结束') > -1
|
||||
},
|
||||
showWinList(item) {
|
||||
this.winList = []
|
||||
this.showWinModal = true
|
||||
this.$u.api.getWenjuanWinDetailList({
|
||||
wenjuan_id: 1003,
|
||||
period: item.index
|
||||
}).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.winList = Array.isArray(res.Data) ? res.Data : []
|
||||
} else {
|
||||
uni.showToast({ title: res.msg || '加载失败', icon: 'none' })
|
||||
}
|
||||
}).catch(() => {
|
||||
uni.showToast({ title: '网络异常', icon: 'none' })
|
||||
})
|
||||
},
|
||||
closeWinModal() {
|
||||
this.showWinModal = false
|
||||
},
|
||||
redeem(item) {
|
||||
const level = Number(item.is_win_level)
|
||||
uni.navigateTo({
|
||||
url: '/pages/redeem/redeem?level=' + level + '&period=' + item.index
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: #6EC5E3;
|
||||
}
|
||||
|
||||
.content {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.page-body {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
flex: 1;
|
||||
padding: 220rpx 30rpx 20rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.login-box {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.login-tip {
|
||||
font-size: 28rpx;
|
||||
color: rgba(255,255,255,0.85);
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
.login-btn {
|
||||
width: 400rpx;
|
||||
height: 80rpx;
|
||||
line-height: 80rpx;
|
||||
background: linear-gradient(135deg, #FD5401, #FF7A3D);
|
||||
color: #fff;
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
border: none;
|
||||
border-radius: 40rpx;
|
||||
box-shadow: 0 4rpx 16rpx rgba(253,84,1,0.3);
|
||||
}
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
.header-icon {
|
||||
font-size: 52rpx;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-size: 36rpx;
|
||||
font-weight: 800;
|
||||
color: #fff;
|
||||
text-shadow: 0 2rpx 8rpx rgba(0,0,0,0.15);
|
||||
letter-spacing: 4rpx;
|
||||
}
|
||||
|
||||
.header-line {
|
||||
width: 60rpx;
|
||||
height: 4rpx;
|
||||
background: rgba(255,255,255,0.5);
|
||||
border-radius: 2rpx;
|
||||
margin-top: 12rpx;
|
||||
}
|
||||
|
||||
.record-list {
|
||||
background: rgba(255,255,255,0.95);
|
||||
border-radius: 20rpx;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 4rpx 20rpx rgba(0,0,0,0.06);
|
||||
}
|
||||
|
||||
.record-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 28rpx 24rpx;
|
||||
border-bottom: 1rpx solid #f0f0f0;
|
||||
}
|
||||
|
||||
.record-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.record-icon {
|
||||
width: 56rpx;
|
||||
height: 56rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
margin-right: 16rpx;
|
||||
background: #fff7e6;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.record-icon .iconfont {
|
||||
font-size: 32rpx;
|
||||
}
|
||||
|
||||
.record-info {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.record-prize {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.record-desc {
|
||||
font-size: 22rpx;
|
||||
color: #999;
|
||||
margin-top: 4rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.record-status {
|
||||
font-size: 22rpx;
|
||||
color: #FD5401;
|
||||
margin-top: 4rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.record-right {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
flex-shrink: 0;
|
||||
margin-left: 16rpx;
|
||||
min-width: 260rpx;
|
||||
}
|
||||
|
||||
.record-time {
|
||||
font-size: 22rpx;
|
||||
color: #bbb;
|
||||
margin-bottom: 8rpx;
|
||||
text-align: right;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.btn-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12rpx;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.winlist-btn {
|
||||
flex: 1;
|
||||
height: 60rpx;
|
||||
line-height: 60rpx;
|
||||
background: linear-gradient(135deg, #E0B866, #F0D08A);
|
||||
color: #fff;
|
||||
font-size: 24rpx;
|
||||
font-weight: 600;
|
||||
border: none;
|
||||
border-radius: 30rpx;
|
||||
padding: 0 12rpx;
|
||||
margin: 0;
|
||||
letter-spacing: 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.redeem-btn {
|
||||
flex: 1;
|
||||
height: 60rpx;
|
||||
line-height: 60rpx;
|
||||
background: linear-gradient(135deg, rgba(253,84,1,0.85), rgba(255,122,61,0.85));
|
||||
color: #fff;
|
||||
font-size: 24rpx;
|
||||
font-weight: 600;
|
||||
border: none;
|
||||
border-radius: 30rpx;
|
||||
box-shadow: 0 4rpx 12rpx rgba(253,84,1,0.3);
|
||||
padding: 0 12rpx;
|
||||
margin: 0;
|
||||
letter-spacing: 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.empty-box {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 80rpx 0;
|
||||
}
|
||||
|
||||
.empty-icon {
|
||||
font-size: 80rpx;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
font-size: 26rpx;
|
||||
color: rgba(255,255,255,0.7);
|
||||
}
|
||||
|
||||
.modal-mask {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0,0,0,0.5);
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.modal {
|
||||
position: fixed;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 600rpx;
|
||||
background: #fff;
|
||||
border-radius: 24rpx;
|
||||
z-index: 101;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.modal-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 30rpx 30rpx 20rpx;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.modal-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.modal-close {
|
||||
position: absolute;
|
||||
right: 30rpx;
|
||||
top: 30rpx;
|
||||
font-size: 28rpx;
|
||||
color: #999;
|
||||
padding: 8rpx;
|
||||
}
|
||||
|
||||
.win-modal {
|
||||
max-height: 80vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.win-list {
|
||||
flex: 1;
|
||||
max-height: 60vh;
|
||||
overflow-y: auto;
|
||||
padding: 0 30rpx 30rpx;
|
||||
}
|
||||
|
||||
.win-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 22rpx 0;
|
||||
border-bottom: 1rpx solid #f0f0f0;
|
||||
}
|
||||
|
||||
.win-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.win-level {
|
||||
width: 120rpx;
|
||||
height: 44rpx;
|
||||
line-height: 44rpx;
|
||||
text-align: center;
|
||||
border-radius: 22rpx;
|
||||
font-size: 22rpx;
|
||||
color: #fff;
|
||||
flex-shrink: 0;
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
|
||||
.win-level-1 {
|
||||
background: linear-gradient(135deg, #E0B866, #F0D08A);
|
||||
}
|
||||
|
||||
.win-level-2 {
|
||||
background: linear-gradient(135deg, #B8B8B8, #D8D8D8);
|
||||
}
|
||||
|
||||
.win-level-3 {
|
||||
background: linear-gradient(135deg, #CD9B6A, #E0B88A);
|
||||
}
|
||||
|
||||
.win-name {
|
||||
flex: 1;
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.win-phone {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
flex-shrink: 0;
|
||||
margin-left: 16rpx;
|
||||
}
|
||||
|
||||
.win-empty {
|
||||
text-align: center;
|
||||
font-size: 26rpx;
|
||||
color: #999;
|
||||
padding: 60rpx 0;
|
||||
}
|
||||
|
||||
::v-deep .u-tabbar__content {
|
||||
background: linear-gradient(to bottom, #FAFFC7, #B2FFC9) !important;
|
||||
}
|
||||
|
||||
::v-deep .u-tabbar__content__item {
|
||||
background: linear-gradient(to bottom, #FAFFC7, #B2FFC9) !important;
|
||||
}
|
||||
|
||||
::v-deep .u-tabbar {
|
||||
.u-border-top {
|
||||
border-top: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .u-icon__img {
|
||||
object-fit: contain !important;
|
||||
}
|
||||
|
||||
::v-deep .u-tabbar__content__item {
|
||||
padding: 16rpx 0 !important;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,376 @@
|
||||
<template>
|
||||
<view class="content">
|
||||
<view class="page-header">
|
||||
<text class="header-back" @tap="goBack">‹</text>
|
||||
<text class="header-title">兑奖</text>
|
||||
</view>
|
||||
<view class="page-wrap">
|
||||
<view class="prize-card">
|
||||
<view class="prize-title">{{ prizeText }}</view>
|
||||
<view class="prize-box" v-if="prizeOptions.length === 0 && prizeImages.length > 0">
|
||||
<image class="prize-main-img" :src="prizeImages[0]" mode="widthFix"></image>
|
||||
<text class="prize-desc" v-if="prizeContent">{{ prizeContent }}</text>
|
||||
</view>
|
||||
<view class="prize-options" v-if="prizeOptions.length > 0">
|
||||
<text class="field-label">请选择奖品(5选1)</text>
|
||||
<view class="prize-grid">
|
||||
<view class="prize-grid-item" v-for="(opt, oi) in prizeOptions" :key="oi"
|
||||
:class="{ active: selectedOption === opt.key }"
|
||||
@tap="selectOption(opt)">
|
||||
<view class="prize-grid-img-wrap">
|
||||
<image class="prize-grid-img" :src="opt.images[0]" mode="aspectFill"></image>
|
||||
<view class="prize-grid-mark" :class="{ checked: selectedOption === opt.key }">
|
||||
<text v-if="selectedOption === opt.key">✓</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="prize-grid-name-row">
|
||||
<text class="prize-grid-name">{{ opt.name }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="form-card">
|
||||
<view class="form-field">
|
||||
<text class="field-label">姓名</text>
|
||||
<input class="field-input" v-model="userName" placeholder="请输入姓名" placeholder-class="input-placeholder" />
|
||||
</view>
|
||||
<view class="form-field">
|
||||
<text class="field-label">手机号码</text>
|
||||
<view class="field-value-static">{{ userPhone }}</view>
|
||||
</view>
|
||||
<view class="form-field">
|
||||
<text class="field-label">身份证号码</text>
|
||||
<input class="field-input" v-model="idCard" placeholder="请输入身份证号码" placeholder-class="input-placeholder" />
|
||||
</view>
|
||||
</view>
|
||||
<button class="submit-btn" @tap="submitRedeem">确认兑奖</button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
level: 0,
|
||||
period: '',
|
||||
prizeText: '',
|
||||
prizeContent: '',
|
||||
prizeImages: [],
|
||||
prizeOptions: [],
|
||||
selectedOption: '',
|
||||
userName: '',
|
||||
userPhone: '',
|
||||
idCard: ''
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
this.level = Number(options.level) || 0
|
||||
this.period = options.period || ''
|
||||
this.userName = uni.getStorageSync('userNameGift') || ''
|
||||
this.userPhone = uni.getStorageSync('userPhoneGift') || ''
|
||||
if (this.level === 1) {
|
||||
this.prizeText = '恭喜您中了一等奖'
|
||||
this.prizeContent = '2026学法有礼一等奖'
|
||||
this.prizeImages = ['https://aliyunoss.hn12301.net/learnlaw/gift_cztk.png']
|
||||
} else if (this.level === 2) {
|
||||
this.prizeText = '恭喜您中了二等奖'
|
||||
this.prizeOptions = [
|
||||
{ key: 'prize_option1', name: '永州卡', prize_type: 18, images: ['https://aliyunoss.hn12301.net/learnlaw/gift_yzk.png'] },
|
||||
{ key: 'prize_option2', name: '郴州卡', prize_type: 19, images: ['https://aliyunoss.hn12301.net/learnlaw/gift_czk.png'] },
|
||||
{ key: 'prize_option3', name: '怀化卡', prize_type: 20, images: ['https://aliyunoss.hn12301.net/learnlaw/gift_hhk.png'] },
|
||||
{ key: 'prize_option4', name: '邵阳卡', prize_type: 21, images: ['https://aliyunoss.hn12301.net/learnlaw/gift_syk.png'] },
|
||||
{ key: 'prize_option5', name: '益阳卡', prize_type: 22, images: ['https://aliyunoss.hn12301.net/learnlaw/gift_yyk.png'] }
|
||||
]
|
||||
} else if (this.level === 3) {
|
||||
this.prizeText = '恭喜您中了三等奖'
|
||||
this.prizeContent = '2026学法有礼三等奖'
|
||||
this.prizeImages = ['https://aliyunoss.hn12301.net/learnlaw/gift_jxxxk.png']
|
||||
} else {
|
||||
this.prizeText = '恭喜您中奖'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
goBack() {
|
||||
uni.navigateBack()
|
||||
},
|
||||
selectOption(opt) {
|
||||
this.selectedOption = opt.key
|
||||
},
|
||||
submitRedeem() {
|
||||
if (!this.userName) {
|
||||
uni.showToast({ title: '请输入姓名', icon: 'none' })
|
||||
return
|
||||
}
|
||||
if (this.prizeOptions.length > 0 && !this.selectedOption) {
|
||||
uni.showToast({ title: '请选择奖品', icon: 'none' })
|
||||
return
|
||||
}
|
||||
if (!this.idCard) {
|
||||
uni.showToast({ title: '请输入身份证号码', icon: 'none' })
|
||||
return
|
||||
}
|
||||
if (!/^\d{15}$|^\d{17}[\dXx]$/.test(this.idCard)) {
|
||||
uni.showToast({ title: '身份证号码格式不正确', icon: 'none' })
|
||||
return
|
||||
}
|
||||
let prizeType = null
|
||||
if (this.level === 1) {
|
||||
prizeType = 17
|
||||
} else if (this.level === 2) {
|
||||
const opt = this.prizeOptions.find(o => o.key === this.selectedOption)
|
||||
prizeType = opt ? opt.prize_type : null
|
||||
} else if (this.level === 3) {
|
||||
prizeType = 23
|
||||
}
|
||||
this.$u.api.exchangePrize({
|
||||
wenjuan_id: 1003,
|
||||
period: this.period,
|
||||
win_level: this.level,
|
||||
user_id: uni.getStorageSync('userIdGift'),
|
||||
prize_type: prizeType,
|
||||
user_name: this.userName,
|
||||
user_card_num: this.idCard,
|
||||
address: ''
|
||||
}).then(res => {
|
||||
if (res.code === 0) {
|
||||
uni.showToast({ title: '兑奖成功', icon: 'none' })
|
||||
setTimeout(() => {
|
||||
uni.navigateBack()
|
||||
}, 1200)
|
||||
} else {
|
||||
uni.showToast({ title: res.msg || '兑奖失败', icon: 'none' })
|
||||
}
|
||||
}).catch(() => {
|
||||
uni.showToast({ title: '网络异常', icon: 'none' })
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: #F5F5F5;
|
||||
}
|
||||
|
||||
.content {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 100vh;
|
||||
min-height: 100dvh;
|
||||
}
|
||||
|
||||
.page-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 20rpx 30rpx;
|
||||
background: linear-gradient(135deg, #FD5401, #FF7A3D);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.header-back {
|
||||
font-size: 48rpx;
|
||||
color: #fff;
|
||||
line-height: 1;
|
||||
margin-right: 16rpx;
|
||||
padding: 0 10rpx;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.page-wrap {
|
||||
padding: 24rpx 24rpx 60rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.prize-card {
|
||||
background: #fff;
|
||||
border-radius: 20rpx;
|
||||
padding: 30rpx 24rpx;
|
||||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.05);
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.prize-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
text-align: center;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.prize-box {
|
||||
background: linear-gradient(135deg, #FDF6E8 0%, #FEF3E0 100%);
|
||||
border: 2rpx solid #F5E3C8;
|
||||
border-radius: 20rpx;
|
||||
padding: 30rpx 24rpx 24rpx;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.prize-box::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 6rpx;
|
||||
background: linear-gradient(to right, #FD5401, #E0B866, #FD5401);
|
||||
}
|
||||
|
||||
.prize-main-img {
|
||||
width: 400rpx;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
|
||||
.prize-desc {
|
||||
font-size: 24rpx;
|
||||
color: #8B6A3E;
|
||||
display: block;
|
||||
margin-top: 16rpx;
|
||||
line-height: 1.6;
|
||||
font-weight: 500;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.prize-options {
|
||||
margin-top: 8rpx;
|
||||
}
|
||||
|
||||
.prize-grid {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.prize-grid-item {
|
||||
width: 319rpx;
|
||||
box-sizing: border-box;
|
||||
border: 2rpx solid #eee;
|
||||
border-radius: 14rpx;
|
||||
background: #FEFCF8;
|
||||
overflow: hidden;
|
||||
margin-right: 16rpx;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.prize-grid-item:nth-child(2n) {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.prize-grid-item.active {
|
||||
border-color: #FD5401;
|
||||
background: #FFF4EC;
|
||||
box-shadow: 0 4rpx 12rpx rgba(253, 84, 1, 0.15);
|
||||
}
|
||||
|
||||
.prize-grid-img-wrap {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 210rpx;
|
||||
}
|
||||
|
||||
.prize-grid-img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.prize-grid-mark {
|
||||
position: absolute;
|
||||
top: 12rpx;
|
||||
right: 12rpx;
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
line-height: 36rpx;
|
||||
text-align: center;
|
||||
border-radius: 50%;
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
border: 2rpx solid #ccc;
|
||||
color: #fff;
|
||||
font-size: 24rpx;
|
||||
font-weight: 700;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.prize-grid-mark.checked {
|
||||
background: #FD5401;
|
||||
border-color: #FD5401;
|
||||
box-shadow: 0 2rpx 8rpx rgba(253, 84, 1, 0.4);
|
||||
}
|
||||
|
||||
.prize-grid-name-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 16rpx 10rpx;
|
||||
}
|
||||
|
||||
.prize-grid-name {
|
||||
font-size: 26rpx;
|
||||
color: #333;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.form-card {
|
||||
background: #fff;
|
||||
border-radius: 20rpx;
|
||||
padding: 10rpx 24rpx;
|
||||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.05);
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
.form-field {
|
||||
padding: 20rpx 0;
|
||||
border-bottom: 1rpx solid #f5f5f5;
|
||||
}
|
||||
|
||||
.form-field:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.field-label {
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
display: block;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.field-value-static {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
padding: 8rpx 0;
|
||||
}
|
||||
|
||||
.field-input {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
padding: 8rpx 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.input-placeholder {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.submit-btn {
|
||||
width: 100%;
|
||||
height: 88rpx;
|
||||
line-height: 88rpx;
|
||||
background: linear-gradient(135deg, #FD5401, #FF7A3D);
|
||||
color: #fff;
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
border: none;
|
||||
border-radius: 44rpx;
|
||||
box-shadow: 0 4rpx 16rpx rgba(253, 84, 1, 0.4);
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,357 @@
|
||||
<template>
|
||||
<view class="register-page">
|
||||
<view class="header">
|
||||
<!-- <text class="header-title">注册信息</text> -->
|
||||
<text class="header-desc">填写参与活动信息</text>
|
||||
</view>
|
||||
<view class="form">
|
||||
<view class="field">
|
||||
<text class="label">姓名</text>
|
||||
<view class="input-wrap">
|
||||
<text class="input-icon">👤</text>
|
||||
<input class="input" v-model="userName" placeholder="请输入您的姓名" />
|
||||
</view>
|
||||
<view class="notice">
|
||||
<view class="notice-icon">⚠️</view>
|
||||
<text class="notice-text">为保障活动公平及奖品顺利发放,请使用本人实名信息注册,中奖后需凭有效身份信息核验兑奖。</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="field">
|
||||
<text class="label">手机号</text>
|
||||
<view class="input-wrap">
|
||||
<text class="input-icon">📱</text>
|
||||
<input class="input" v-model="phone" placeholder="请输入手机号" type="number" maxlength="11" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="field">
|
||||
<text class="label">验证码</text>
|
||||
<view class="field-row">
|
||||
<view class="input-wrap code-input-wrap">
|
||||
<text class="input-icon">✉️</text>
|
||||
<input class="input" v-model="smsCode" placeholder="请输入验证码" type="number" maxlength="6" />
|
||||
</view>
|
||||
<button class="code-btn" @tap="sendCode" :disabled="sending" :class="{ disabled: sending }">
|
||||
{{ sending ? countdown + 's' : '获取验证码' }}
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
<view class="agree-row" @tap="agreed = !agreed">
|
||||
<view class="agree-checkbox" :class="{ checked: agreed }">
|
||||
<text v-if="agreed" class="agree-check-mark">✓</text>
|
||||
</view>
|
||||
<view class="agree-text">
|
||||
<text>我已阅读并同意</text>
|
||||
<text class="agree-link" @tap.stop="goPrivacy">《用户隐私协议》</text>
|
||||
</view>
|
||||
</view>
|
||||
<button class="submit-btn" @tap="register" :disabled="submitting" :class="{ disabled: submitting }">
|
||||
{{ submitting ? '提交中...' : '立即提交' }}
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
userName: '',
|
||||
phone: '',
|
||||
smsCode: '',
|
||||
agreed: false,
|
||||
sending: false,
|
||||
countdown: 60,
|
||||
timer: null,
|
||||
submitting: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
sendCode() {
|
||||
if (!/^1\d{10}$/.test(this.phone)) {
|
||||
uni.showToast({ title: '请输入正确手机号', icon: 'none' })
|
||||
return
|
||||
}
|
||||
this.sending = true
|
||||
this.$u.api.sendSms(this.phone).then(res => {
|
||||
if (res.code === 0) {
|
||||
uni.showToast({ title: '验证码已发送', icon: 'none' })
|
||||
this.startCountdown()
|
||||
} else {
|
||||
uni.showToast({ title: res.msg || '发送失败', icon: 'none' })
|
||||
this.sending = false
|
||||
}
|
||||
}).catch(() => {
|
||||
uni.showToast({ title: '网络错误', icon: 'none' })
|
||||
this.sending = false
|
||||
})
|
||||
},
|
||||
startCountdown() {
|
||||
this.countdown = 60
|
||||
this.timer = setInterval(() => {
|
||||
this.countdown--
|
||||
if (this.countdown <= 0) {
|
||||
clearInterval(this.timer)
|
||||
this.timer = null
|
||||
this.sending = false
|
||||
}
|
||||
}, 1000)
|
||||
},
|
||||
goPrivacy() {
|
||||
uni.navigateTo({ url: '/pages/privacy/privacy' })
|
||||
},
|
||||
register() {
|
||||
if (!this.userName || !this.phone || !this.smsCode) {
|
||||
uni.showToast({ title: '请填写完整信息', icon: 'none' })
|
||||
return
|
||||
}
|
||||
if (!this.agreed) {
|
||||
uni.showToast({ title: '请先阅读并同意《用户隐私协议》', icon: 'none' })
|
||||
return
|
||||
}
|
||||
this.submitting = true
|
||||
const openId = uni.getStorageSync('openIdGift')
|
||||
this.$u.api.userRegist({
|
||||
wenjuan_id: 1003,
|
||||
open_id: openId,
|
||||
user_name: this.userName,
|
||||
user_phone: this.phone,
|
||||
sms_code: this.smsCode,
|
||||
channel: 1
|
||||
}).then(res => {
|
||||
if (res.code === 0) {
|
||||
uni.setStorageSync('isRegisteredGift', true)
|
||||
const data = res.Data || {}
|
||||
const userId = data.user_id || data.uesr_id
|
||||
if (userId) uni.setStorageSync('userIdGift', userId)
|
||||
if (data.user_name) uni.setStorageSync('userNameGift', data.user_name)
|
||||
if (data.user_phone) uni.setStorageSync('userPhoneGift', data.user_phone)
|
||||
this.syncUserInfo(openId)
|
||||
uni.showToast({ title: '注册成功' })
|
||||
setTimeout(() => uni.navigateBack(), 1500)
|
||||
} else {
|
||||
uni.showToast({ title: res.msg || '注册失败', icon: 'none' })
|
||||
}
|
||||
}).catch(() => {
|
||||
uni.showToast({ title: '网络错误', icon: 'none' })
|
||||
}).finally(() => {
|
||||
this.submitting = false
|
||||
})
|
||||
},
|
||||
syncUserInfo(openId) {
|
||||
this.$u.api.wxOpenidLogin({ wenjuan_id: 1003, open_id: openId }).then(loginRes => {
|
||||
if (loginRes && loginRes.code === 0 && loginRes.Data) {
|
||||
const data = loginRes.Data
|
||||
if (data.user_id || data.uesr_id) uni.setStorageSync('userIdGift', data.user_id || data.uesr_id)
|
||||
if (data.user_name) uni.setStorageSync('userNameGift', data.user_name)
|
||||
if (data.user_phone) uni.setStorageSync('userPhoneGift', data.user_phone)
|
||||
}
|
||||
}).catch(err => {
|
||||
console.error('注册后同步用户信息失败', err)
|
||||
})
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (this.timer) {
|
||||
clearInterval(this.timer)
|
||||
this.timer = null
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page {
|
||||
background: linear-gradient(135deg, #FFF8ED 0%, #FFE9C4 100%);
|
||||
}
|
||||
|
||||
.register-page {
|
||||
padding: 60rpx 40rpx;
|
||||
min-height: 100vh;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.header {
|
||||
margin-bottom: 50rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-size: 40rpx;
|
||||
font-weight: bold;
|
||||
color: #5D533D;
|
||||
display: block;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.header-desc {
|
||||
font-size: 26rpx;
|
||||
color: #8B7355;
|
||||
}
|
||||
|
||||
.form {
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
border-radius: 24rpx;
|
||||
padding: 50rpx 40rpx;
|
||||
box-shadow: 0 8rpx 40rpx rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
|
||||
.field {
|
||||
margin-bottom: 36rpx;
|
||||
}
|
||||
|
||||
.label {
|
||||
font-size: 28rpx;
|
||||
font-weight: 500;
|
||||
color: #5D533D;
|
||||
margin-bottom: 16rpx;
|
||||
display: block;
|
||||
padding-left: 8rpx;
|
||||
}
|
||||
|
||||
.input-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 88rpx;
|
||||
border: 2rpx solid #F0E4D0;
|
||||
border-radius: 12rpx;
|
||||
background: #FEFCF8;
|
||||
padding: 0 24rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.input-wrap:focus-within {
|
||||
border-color: #FD5401;
|
||||
box-shadow: 0 0 0 4rpx rgba(253, 84, 1, 0.08);
|
||||
}
|
||||
|
||||
.input-icon {
|
||||
font-size: 32rpx;
|
||||
margin-right: 16rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.input {
|
||||
height: 100%;
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
flex: 1;
|
||||
border: none;
|
||||
background: transparent;
|
||||
outline: none;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.field-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.code-input-wrap {
|
||||
flex: 1;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.code-btn {
|
||||
flex-shrink: 0;
|
||||
height: 88rpx;
|
||||
line-height: 88rpx;
|
||||
padding: 0 28rpx;
|
||||
font-size: 26rpx;
|
||||
color: #FD5401;
|
||||
background: #FFF0E6;
|
||||
border: none;
|
||||
border-radius: 12rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.code-btn.disabled {
|
||||
color: #B8A898;
|
||||
background: #F0E8E0;
|
||||
}
|
||||
|
||||
.submit-btn {
|
||||
width: 100%;
|
||||
height: 96rpx;
|
||||
line-height: 96rpx;
|
||||
background: linear-gradient(135deg, #FD5401, #FF7A3D);
|
||||
color: #fff;
|
||||
font-size: 34rpx;
|
||||
font-weight: 600;
|
||||
border: none;
|
||||
border-radius: 16rpx;
|
||||
margin-top: 20rpx;
|
||||
box-shadow: 0 6rpx 20rpx rgba(253, 84, 1, 0.3);
|
||||
}
|
||||
|
||||
.submit-btn.disabled {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.notice {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
margin-top: 16rpx;
|
||||
padding: 26rpx 28rpx;
|
||||
background: linear-gradient(135deg, #FFF3F3 0%, #FFE9E9 100%);
|
||||
border-radius: 16rpx;
|
||||
box-shadow: 0 4rpx 16rpx rgba(230, 67, 64, 0.12);
|
||||
}
|
||||
|
||||
.notice-icon {
|
||||
font-size: 32rpx;
|
||||
line-height: 1.4;
|
||||
margin-right: 14rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.notice-text {
|
||||
flex: 1;
|
||||
font-size: 26rpx;
|
||||
font-weight: 600;
|
||||
color: #E64340;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.agree-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: -16rpx 8rpx 28rpx;
|
||||
}
|
||||
|
||||
.agree-checkbox {
|
||||
width: 36rpx;
|
||||
height: 36rpx;
|
||||
border: 2rpx solid #CCC;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
margin-right: 12rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.agree-checkbox.checked {
|
||||
border-color: #FD5401;
|
||||
background: #FD5401;
|
||||
}
|
||||
|
||||
.agree-check-mark {
|
||||
font-size: 22rpx;
|
||||
color: #fff;
|
||||
font-weight: 700;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.agree-text {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 24rpx;
|
||||
color: #8B7355;
|
||||
}
|
||||
|
||||
.agree-link {
|
||||
color: #FD5401;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,306 @@
|
||||
<template>
|
||||
<view class="content">
|
||||
<image src="https://aliyunoss.hn12301.net/learnlaw/gift_zt_bj.jpg" mode="widthFix" style="width:750rpx;position:absolute;top:0;left:0;z-index:0;"></image>
|
||||
<view class="page-body">
|
||||
<view class="stat-grid">
|
||||
<view class="stat-row">
|
||||
<view class="stat-item">
|
||||
<view class="stat-icon icon-correct">
|
||||
<text class="iconfont">✓</text>
|
||||
</view>
|
||||
<text class="stat-num">{{ correctCount }}</text>
|
||||
<text class="stat-label">答对题数</text>
|
||||
</view>
|
||||
<view class="stat-item">
|
||||
<view class="stat-icon icon-accuracy">
|
||||
<text class="iconfont">%</text>
|
||||
</view>
|
||||
<text class="stat-num">{{ accuracy }}%</text>
|
||||
<text class="stat-label">正确率</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="stat-row">
|
||||
<view class="stat-item">
|
||||
<view class="stat-icon icon-time">
|
||||
<text class="iconfont">⏱</text>
|
||||
</view>
|
||||
<text class="stat-num">{{ useTime }}s</text>
|
||||
<text class="stat-label">用时</text>
|
||||
</view>
|
||||
<view class="stat-item">
|
||||
<view class="stat-icon icon-wrong">
|
||||
<text class="iconfont">✗</text>
|
||||
</view>
|
||||
<text class="stat-num">{{ wrongCount }}</text>
|
||||
<text class="stat-label">错题数</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="detail-section">
|
||||
<view class="section-header">
|
||||
<text class="section-title">答题详情</text>
|
||||
<text class="section-subtitle">共 {{ detailList.length }} 题,{{ correctCount }} 对 {{ wrongCount }} 错</text>
|
||||
</view>
|
||||
<view class="detail-item" v-for="(item, i) in detailList" :key="i">
|
||||
<view class="detail-index" :class="item.is_correct || item.status === 1 ? 'correct' : 'wrong'">
|
||||
<text class="detail-index-text">{{ i + 1 }}</text>
|
||||
</view>
|
||||
<view class="detail-body">
|
||||
<text class="detail-q">{{ item.tiku_question_content || '题目' + (i+1) }}</text>
|
||||
<view class="detail-answer-row">
|
||||
<text class="detail-label">你的答案:</text>
|
||||
<text class="detail-value" :class="item.is_correct || item.status === 1 ? 'text-correct' : 'text-wrong'">{{ item.user_answer || '未作答' }}</text>
|
||||
</view>
|
||||
<view class="detail-answer-row" v-if="!(item.is_correct || item.status === 1)">
|
||||
<text class="detail-label">正确答案:</text>
|
||||
<text class="detail-value text-correct-answer">{{ item.tiku_correct_answer || '-' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
<button class="back-btn" @tap="goBack">返回首页</button>
|
||||
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
correctCount: 0,
|
||||
wrongCount: 0,
|
||||
accuracy: 0,
|
||||
useTime: 0,
|
||||
detailList: []
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
try {
|
||||
const data = uni.getStorageSync('resultDataGift') || {}
|
||||
this.useTime = data.use_time || 0
|
||||
if (data.resultDetailList && data.resultDetailList.length) {
|
||||
this.detailList = data.resultDetailList
|
||||
this.correctCount = data.resultDetailList.filter(r => r.is_correct === true || r.is_correct === 1 || r.status === 1).length
|
||||
this.wrongCount = data.resultDetailList.length - this.correctCount
|
||||
this.accuracy = Math.round(this.correctCount / data.resultDetailList.length * 100)
|
||||
}
|
||||
} catch(e) {
|
||||
console.error('解析结果数据失败', e)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
goBack() {
|
||||
uni.switchTab({ url: '/pages/index/index' })
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: #7CC6EB;
|
||||
}
|
||||
|
||||
.content {
|
||||
position: relative;
|
||||
height: 100vh;
|
||||
height: 100dvh;
|
||||
|
||||
}
|
||||
|
||||
.page-body {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
height: 100%;
|
||||
padding: 40rpx 30rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.stat-grid {
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.stat-row {
|
||||
display: flex;
|
||||
gap: 14rpx;
|
||||
margin-bottom: 14rpx;
|
||||
}
|
||||
|
||||
.stat-row:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.stat-item {
|
||||
flex: 1;
|
||||
background: rgba(255,255,255,0.95);
|
||||
border-radius: 16rpx;
|
||||
padding: 20rpx 12rpx 18rpx;
|
||||
text-align: center;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.04);
|
||||
}
|
||||
|
||||
.stat-icon {
|
||||
width: 44rpx;
|
||||
height: 44rpx;
|
||||
border-radius: 50%;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.stat-icon .iconfont {
|
||||
font-size: 22rpx;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.icon-correct { background: #f6ffed; }
|
||||
.icon-correct .iconfont { color: #52c41a; }
|
||||
.icon-accuracy { background: #fff7e6; }
|
||||
.icon-accuracy .iconfont { color: #fa8c16; }
|
||||
.icon-time { background: #e6f7ff; }
|
||||
.icon-time .iconfont { color: #1890ff; }
|
||||
.icon-wrong { background: #fff1f0; }
|
||||
.icon-wrong .iconfont { color: #f5222d; }
|
||||
|
||||
.stat-num {
|
||||
display: block;
|
||||
font-size: 34rpx;
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
margin-bottom: 4rpx;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 22rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.detail-section {
|
||||
background: rgba(255,255,255,0.95);
|
||||
border-radius: 20rpx;
|
||||
padding: 28rpx;
|
||||
margin-bottom: 30rpx;
|
||||
|
||||
box-shadow: 0 2rpx 12rpx rgba(0,0,0,0.04);
|
||||
}
|
||||
|
||||
.section-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: baseline;
|
||||
margin-bottom: 20rpx;
|
||||
padding-bottom: 16rpx;
|
||||
border-bottom: 2rpx solid #f5f5f5;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 30rpx;
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.section-subtitle {
|
||||
font-size: 24rpx;
|
||||
color: #bbb;
|
||||
}
|
||||
|
||||
.detail-item {
|
||||
padding: 20rpx 0;
|
||||
border-bottom: 1rpx solid #f0f0f0;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.detail-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.detail-index {
|
||||
width: 44rpx;
|
||||
height: 44rpx;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
margin-right: 16rpx;
|
||||
margin-top: 2rpx;
|
||||
}
|
||||
|
||||
.detail-index.correct {
|
||||
background: linear-gradient(135deg, #52c41a, #73d13d);
|
||||
box-shadow: 0 2rpx 8rpx rgba(82,196,26,0.3);
|
||||
}
|
||||
|
||||
.detail-index.wrong {
|
||||
background: linear-gradient(135deg, #f5222d, #ff4d4f);
|
||||
box-shadow: 0 2rpx 8rpx rgba(245,34,45,0.3);
|
||||
}
|
||||
|
||||
.detail-index-text {
|
||||
font-size: 20rpx;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.detail-body {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.detail-q {
|
||||
font-size: 26rpx;
|
||||
color: #333;
|
||||
line-height: 1.5;
|
||||
display: block;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.detail-answer-row {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
margin-top: 4rpx;
|
||||
}
|
||||
|
||||
.detail-label {
|
||||
font-size: 22rpx;
|
||||
color: #999;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.detail-value {
|
||||
font-size: 24rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.text-correct {
|
||||
color: #52c41a;
|
||||
}
|
||||
|
||||
.text-wrong {
|
||||
color: #f5222d;
|
||||
}
|
||||
|
||||
.text-correct-answer {
|
||||
color: #52c41a;
|
||||
}
|
||||
|
||||
.back-btn {
|
||||
width: 690rpx;
|
||||
|
||||
height: 88rpx;
|
||||
line-height: 88rpx;
|
||||
background: linear-gradient(135deg, #FD5401, #FF7A3D);
|
||||
color: #fff;
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
border: none;
|
||||
border-radius: 44rpx;
|
||||
box-shadow: 0 4rpx 16rpx rgba(253,84,1,0.3);
|
||||
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,220 @@
|
||||
<template>
|
||||
<view class="content">
|
||||
<view class="page-header">
|
||||
<text class="header-back" @tap="goBack">‹</text>
|
||||
<text class="header-title">活动规则</text>
|
||||
</view>
|
||||
<view class="preview-wrap">
|
||||
<view class="loading-box" v-if="loading">
|
||||
<u-loading mode="circle" size="40"></u-loading>
|
||||
<text class="loading-text">内容加载中...</text>
|
||||
</view>
|
||||
<scroll-view class="doc-scroll" scroll-y v-if="!loading && !error">
|
||||
<rich-text class="doc-content" :nodes="htmlContent"></rich-text>
|
||||
<view style="height:30rpx;"></view>
|
||||
</scroll-view>
|
||||
<view class="error-box" v-if="error">
|
||||
<text class="error-text">{{ error }}</text>
|
||||
<button class="preview-btn" @tap="loadDoc">重新加载</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
docUrl: 'https://goldnar.hntgov.net/img/gift_rules.docx',
|
||||
loading: false,
|
||||
error: '',
|
||||
htmlContent: ''
|
||||
}
|
||||
},
|
||||
onReady() {
|
||||
this.loadDoc()
|
||||
},
|
||||
methods: {
|
||||
goBack() {
|
||||
uni.navigateBack()
|
||||
},
|
||||
loadDoc() {
|
||||
this.loading = true
|
||||
this.error = ''
|
||||
this.htmlContent = ''
|
||||
this.ensureMammoth().then(() => {
|
||||
return this.fetchDocx(this.docUrl)
|
||||
}).then(arrayBuffer => {
|
||||
return window.mammoth.convertToHtml({
|
||||
arrayBuffer
|
||||
})
|
||||
}).then(result => {
|
||||
this.htmlContent = result.value || ''
|
||||
this.loading = false
|
||||
}).catch(err => {
|
||||
console.error('加载文档失败', err)
|
||||
this.loading = false
|
||||
this.error = '文档加载失败,请重试'
|
||||
})
|
||||
},
|
||||
ensureMammoth() {
|
||||
if (window.mammoth) return Promise.resolve()
|
||||
return new Promise((resolve, reject) => {
|
||||
const urls = [
|
||||
'/static/mammoth.browser.min.js',
|
||||
'https://unpkg.com/mammoth@1.6.0/mammoth.browser.min.js'
|
||||
]
|
||||
let i = 0
|
||||
const loadNext = () => {
|
||||
if (i >= urls.length) {
|
||||
reject(new Error('解析组件加载失败'))
|
||||
return
|
||||
}
|
||||
const s = document.createElement('script')
|
||||
s.src = urls[i++]
|
||||
s.onload = () => window.mammoth ? resolve() : loadNext()
|
||||
s.onerror = loadNext
|
||||
document.head.appendChild(s)
|
||||
}
|
||||
loadNext()
|
||||
})
|
||||
},
|
||||
fetchDocx(url) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (typeof fetch !== 'undefined') {
|
||||
fetch(url).then(res => {
|
||||
if (!res.ok) throw new Error('HTTP ' + res.status)
|
||||
return res.arrayBuffer()
|
||||
}).then(resolve).catch(() => this.downloadDocx(url).then(resolve).catch(reject))
|
||||
return
|
||||
}
|
||||
this.downloadDocx(url).then(resolve).catch(reject)
|
||||
})
|
||||
},
|
||||
downloadDocx(url) {
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.downloadFile({
|
||||
url: url,
|
||||
success: (res) => {
|
||||
if (res.statusCode !== 200) {
|
||||
reject(new Error('下载失败'))
|
||||
return
|
||||
}
|
||||
uni.getFileSystemManager().readFile({
|
||||
filePath: res.tempFilePath,
|
||||
success: (r) => resolve(r.data),
|
||||
fail: () => {
|
||||
if (res.tempFilePath && typeof fetch !== 'undefined') {
|
||||
fetch(res.tempFilePath).then(r => r.arrayBuffer())
|
||||
.then(resolve).catch(reject)
|
||||
} else {
|
||||
reject(new Error('读取文件失败'))
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
fail: reject
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: #F8F8F8;
|
||||
}
|
||||
|
||||
.content {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100vh;
|
||||
height: 100dvh;
|
||||
}
|
||||
|
||||
.page-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 20rpx 30rpx;
|
||||
background: linear-gradient(135deg, #FD5401, #FF7A3D);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.header-back {
|
||||
font-size: 48rpx;
|
||||
color: #fff;
|
||||
line-height: 1;
|
||||
margin-right: 16rpx;
|
||||
padding: 0 10rpx;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.preview-wrap {
|
||||
flex: 1;
|
||||
background: #fff;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.loading-box {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.loading-text {
|
||||
font-size: 26rpx;
|
||||
color: #999;
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
|
||||
.error-box {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.error-text {
|
||||
font-size: 26rpx;
|
||||
color: #999;
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
.preview-btn {
|
||||
width: 300rpx;
|
||||
height: 76rpx;
|
||||
line-height: 76rpx;
|
||||
background: linear-gradient(135deg, #FD5401, #FF7A3D);
|
||||
color: #fff;
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
border: none;
|
||||
border-radius: 38rpx;
|
||||
}
|
||||
|
||||
.doc-scroll {
|
||||
height: 100%;
|
||||
padding: 20rpx 30rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.doc-content {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
line-height: 1.8;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,336 @@
|
||||
<template>
|
||||
<view class="content">
|
||||
<view class="page-header">
|
||||
<text class="header-title">{{ current.title }}</text>
|
||||
<text class="header-index">{{ currentIndex + 1 }} / {{ articles.length }}</text>
|
||||
</view>
|
||||
<view class="preview-wrap">
|
||||
<view class="loading-box" v-if="loading">
|
||||
<u-loading mode="circle" size="40"></u-loading>
|
||||
<text class="loading-text">内容加载中...</text>
|
||||
</view>
|
||||
<scroll-view class="doc-scroll" scroll-y v-if="!loading && !error">
|
||||
<rich-text class="doc-content" :nodes="htmlContent"></rich-text>
|
||||
<view style="height:30rpx;"></view>
|
||||
</scroll-view>
|
||||
<view class="error-box" v-if="error">
|
||||
<text class="error-text">{{ error }}</text>
|
||||
<button class="preview-btn" @tap="loadArticle">重新加载</button>
|
||||
</view>
|
||||
</view>
|
||||
<view class="page-footer">
|
||||
<button class="nav-btn prev" :disabled="currentIndex <= 0" @tap="prev">上一篇</button>
|
||||
<button class="nav-btn next" :disabled="currentIndex >= articles.length - 1" @tap="next">下一篇</button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
articles: [{
|
||||
title: '中华人民共和国宪法',
|
||||
url: 'https://goldnar.hntgov.net/img/word8.docx'
|
||||
},
|
||||
{
|
||||
title: '中华人民共和国民法典',
|
||||
url: 'https://goldnar.hntgov.net/img/word4.docx'
|
||||
},
|
||||
{
|
||||
title: '中华人民共和国测绘法',
|
||||
url: 'https://goldnar.hntgov.net/img/word13_1.docx'
|
||||
},
|
||||
{
|
||||
title: '中华人民共和国城市房地产管理法',
|
||||
url: 'https://goldnar.hntgov.net/img/word14_1.docx'
|
||||
},
|
||||
{
|
||||
title: '中华人民共和国矿产资源法',
|
||||
url: 'https://goldnar.hntgov.net/img/word15_1.docx'
|
||||
},
|
||||
{
|
||||
title: '中华人民共和国土地管理法',
|
||||
url: 'https://goldnar.hntgov.net/img/word16_1.docx'
|
||||
},
|
||||
{
|
||||
title: '中华人民共和国生态环境法典',
|
||||
url: 'https://goldnar.hntgov.net/img/word9.docx'
|
||||
},
|
||||
{
|
||||
title: '中华人民共和国渔业法',
|
||||
url: 'https://goldnar.hntgov.net/img/word10.docx'
|
||||
},
|
||||
{
|
||||
title: '中华人民共和国农村集体经济组织法',
|
||||
url: 'https://goldnar.hntgov.net/img/word11.docx'
|
||||
},
|
||||
|
||||
{
|
||||
title: '湖南省实施《中华人民共和国法治宣传教育法》办法',
|
||||
url: 'https://goldnar.hntgov.net/img/word1.docx'
|
||||
},
|
||||
{
|
||||
title: '中华人民共和国安全生产法',
|
||||
url: 'https://goldnar.hntgov.net/img/word5.docx'
|
||||
},
|
||||
{
|
||||
title: '中华人民共和国法治宣传教育法',
|
||||
url: 'https://goldnar.hntgov.net/img/word3.docx'
|
||||
},
|
||||
{
|
||||
title: '中华人民共和国乡村振兴促进法',
|
||||
url: 'https://goldnar.hntgov.net/img/word7.docx'
|
||||
}
|
||||
],
|
||||
currentIndex: 0,
|
||||
loading: false,
|
||||
error: '',
|
||||
htmlContent: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
current() {
|
||||
return this.articles[this.currentIndex] || {}
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
const idx = parseInt(options.index)
|
||||
if (!isNaN(idx) && idx >= 0 && idx < this.articles.length) {
|
||||
this.currentIndex = idx
|
||||
} else {
|
||||
this.currentIndex = 0
|
||||
}
|
||||
},
|
||||
onReady() {
|
||||
this.loadArticle()
|
||||
},
|
||||
methods: {
|
||||
prev() {
|
||||
if (this.currentIndex > 0) {
|
||||
this.currentIndex--
|
||||
this.loadArticle()
|
||||
}
|
||||
},
|
||||
next() {
|
||||
if (this.currentIndex < this.articles.length - 1) {
|
||||
this.currentIndex++
|
||||
this.loadArticle()
|
||||
}
|
||||
},
|
||||
loadArticle() {
|
||||
this.loading = true
|
||||
this.error = ''
|
||||
this.htmlContent = ''
|
||||
this.ensureMammoth().then(() => {
|
||||
return this.fetchDocx(this.current.url)
|
||||
}).then(arrayBuffer => {
|
||||
return window.mammoth.convertToHtml({
|
||||
arrayBuffer
|
||||
})
|
||||
}).then(result => {
|
||||
this.htmlContent = result.value || ''
|
||||
this.loading = false
|
||||
}).catch(err => {
|
||||
console.error('加载文档失败', err)
|
||||
this.loading = false
|
||||
this.error = '文档加载失败,请重试'
|
||||
})
|
||||
},
|
||||
ensureMammoth() {
|
||||
if (window.mammoth) return Promise.resolve()
|
||||
return new Promise((resolve, reject) => {
|
||||
const urls = [
|
||||
'/static/mammoth.browser.min.js',
|
||||
'https://unpkg.com/mammoth@1.6.0/mammoth.browser.min.js'
|
||||
]
|
||||
let i = 0
|
||||
const loadNext = () => {
|
||||
if (i >= urls.length) {
|
||||
reject(new Error('解析组件加载失败'))
|
||||
return
|
||||
}
|
||||
const s = document.createElement('script')
|
||||
s.src = urls[i++]
|
||||
s.onload = () => window.mammoth ? resolve() : loadNext()
|
||||
s.onerror = loadNext
|
||||
document.head.appendChild(s)
|
||||
}
|
||||
loadNext()
|
||||
})
|
||||
},
|
||||
fetchDocx(url) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (typeof fetch !== 'undefined') {
|
||||
fetch(url).then(res => {
|
||||
if (!res.ok) throw new Error('HTTP ' + res.status)
|
||||
return res.arrayBuffer()
|
||||
}).then(resolve).catch(() => this.downloadDocx(url).then(resolve).catch(reject))
|
||||
return
|
||||
}
|
||||
this.downloadDocx(url).then(resolve).catch(reject)
|
||||
})
|
||||
},
|
||||
downloadDocx(url) {
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.downloadFile({
|
||||
url: url,
|
||||
success: (res) => {
|
||||
if (res.statusCode !== 200) {
|
||||
reject(new Error('下载失败'))
|
||||
return
|
||||
}
|
||||
uni.getFileSystemManager().readFile({
|
||||
filePath: res.tempFilePath,
|
||||
success: (r) => resolve(r.data),
|
||||
fail: () => {
|
||||
if (res.tempFilePath && typeof fetch !== 'undefined') {
|
||||
fetch(res.tempFilePath).then(r => r.arrayBuffer())
|
||||
.then(resolve).catch(reject)
|
||||
} else {
|
||||
reject(new Error('读取文件失败'))
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
fail: reject
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: #F8F8F8;
|
||||
}
|
||||
|
||||
.content {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.page-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 20rpx 30rpx;
|
||||
background: linear-gradient(135deg, #FD5401, #FF7A3D);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.header-index {
|
||||
font-size: 24rpx;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
|
||||
.preview-wrap {
|
||||
flex: 1;
|
||||
background: #fff;
|
||||
overflow: hidden;
|
||||
padding-bottom: 100rpx;
|
||||
}
|
||||
|
||||
.loading-box {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.loading-text {
|
||||
font-size: 26rpx;
|
||||
color: #999;
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
|
||||
.error-box {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.error-text {
|
||||
font-size: 26rpx;
|
||||
color: #999;
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
.preview-btn {
|
||||
width: 300rpx;
|
||||
height: 76rpx;
|
||||
line-height: 76rpx;
|
||||
background: linear-gradient(135deg, #FD5401, #FF7A3D);
|
||||
color: #fff;
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
border: none;
|
||||
border-radius: 38rpx;
|
||||
}
|
||||
|
||||
.doc-scroll {
|
||||
height: 100%;
|
||||
padding: 20rpx 30rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.doc-content {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
line-height: 1.8;
|
||||
}
|
||||
|
||||
.page-footer {
|
||||
display: flex;
|
||||
gap: 24rpx;
|
||||
padding: 20rpx 30rpx;
|
||||
position: fixed;
|
||||
bottom: 0rpx;
|
||||
width: 750rpx;
|
||||
background: #fff;
|
||||
flex-shrink: 0;
|
||||
border-top: 1rpx solid #f0f0f0;
|
||||
}
|
||||
|
||||
.nav-btn {
|
||||
flex: 1;
|
||||
height: 76rpx;
|
||||
line-height: 76rpx;
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
border: none;
|
||||
border-radius: 38rpx;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.nav-btn.prev {
|
||||
background: #f5f5f5;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.nav-btn.next {
|
||||
background: linear-gradient(135deg, #FD5401, #FF7A3D);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.nav-btn[disabled] {
|
||||
opacity: 0.4;
|
||||
color: #999;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,156 @@
|
||||
<template>
|
||||
<view class="content">
|
||||
<view class="page-body">
|
||||
<image src="https://aliyunoss.hn12301.net/learnlaw/gift_zt_bj.jpg" mode="widthFix" style="width:750rpx;position:absolute;top:0;left:0;z-index:-1;"></image>
|
||||
<view class="header">
|
||||
<view class="header-icon"><text>📖</text></view>
|
||||
<text class="header-title">法制学习</text>
|
||||
<view class="header-line"></view>
|
||||
</view>
|
||||
<view class="doc-list" v-if="articles.length > 0">
|
||||
<view class="doc-item" v-for="(item, i) in articles" :key="i" @tap="openArticle(i)">
|
||||
<view class="doc-icon">
|
||||
<text class="iconfont">📄</text>
|
||||
</view>
|
||||
<view class="doc-info">
|
||||
<text class="doc-title">{{ item.title }}</text>
|
||||
<text class="doc-desc">{{ item.desc }}</text>
|
||||
</view>
|
||||
<view class="doc-arrow">
|
||||
<text>›</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
articles: [
|
||||
{ title: '湖南省实施《中华人民共和国法治宣传教育法》办法', desc: '省级地方性法规', url: 'https://goldnar.hntgov.net/img/word1.docx' },
|
||||
{ title: '全民阅读促进条例', desc: '行政法规', url: 'https://goldnar.hntgov.net/img/word2.docx' },
|
||||
{ title: '中华人民共和国法治宣传教育法', desc: '全国性法律', url: 'https://goldnar.hntgov.net/img/word3.docx' },
|
||||
{ title: '中华人民共和国民法典', desc: '全国性法律', url: 'https://goldnar.hntgov.net/img/word4.docx' }
|
||||
]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
openArticle(i) {
|
||||
uni.navigateTo({ url: '/pages/study/preview?index=' + i })
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: #7CC6EB;
|
||||
}
|
||||
|
||||
.content {
|
||||
position: relative;
|
||||
height: 100vh;
|
||||
height: 100dvh;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.page-body {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
padding: 80rpx 30rpx 20rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
.header-icon {
|
||||
font-size: 52rpx;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-size: 36rpx;
|
||||
font-weight: 800;
|
||||
color: #fff;
|
||||
text-shadow: 0 2rpx 8rpx rgba(0,0,0,0.15);
|
||||
letter-spacing: 4rpx;
|
||||
}
|
||||
|
||||
.header-line {
|
||||
width: 60rpx;
|
||||
height: 4rpx;
|
||||
background: rgba(255,255,255,0.5);
|
||||
border-radius: 2rpx;
|
||||
margin-top: 12rpx;
|
||||
}
|
||||
|
||||
.doc-list {
|
||||
background: rgba(255,255,255,0.95);
|
||||
border-radius: 20rpx;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 4rpx 20rpx rgba(0,0,0,0.06);
|
||||
}
|
||||
|
||||
.doc-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 28rpx 24rpx;
|
||||
border-bottom: 1rpx solid #f0f0f0;
|
||||
}
|
||||
|
||||
.doc-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.doc-icon {
|
||||
width: 56rpx;
|
||||
height: 56rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
margin-right: 16rpx;
|
||||
background: #fff7e6;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.doc-icon .iconfont {
|
||||
font-size: 32rpx;
|
||||
}
|
||||
|
||||
.doc-info {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.doc-title {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.doc-desc {
|
||||
font-size: 22rpx;
|
||||
color: #bbb;
|
||||
margin-top: 4rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.doc-arrow {
|
||||
font-size: 36rpx;
|
||||
color: #ccc;
|
||||
flex-shrink: 0;
|
||||
margin-left: 16rpx;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user