initial commit: giftlaw ni xue fa wo you li - natural resources session
This commit is contained in:
@@ -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