From 0cf1e9bc1e8fc6ac9b6ff0d81acf93307f91bad0 Mon Sep 17 00:00:00 2001
From: yfx <1249361928@.com>
Date: Thu, 19 Mar 2026 11:19:05 +0800
Subject: [PATCH] 137弹框协议
---
components/textBox/index.vue | 329 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 329 insertions(+), 0 deletions(-)
diff --git a/components/textBox/index.vue b/components/textBox/index.vue
new file mode 100644
index 0000000..b988f61
--- /dev/null
+++ b/components/textBox/index.vue
@@ -0,0 +1,329 @@
+<script>
+export default {
+ name: "ProtocolPopup",
+
+ props:{
+ code:{ type:String, default:'' },
+ title:{ type:String, default:'' },
+ getPlatformProtocolNewList:{
+ type:Array,
+ default:() => []
+ }
+ },
+
+ data(){
+ return {
+ list: [],
+ text:'',
+ titleText:'',
+ flag:false,
+ ing:0,
+ scrollTop: 0,
+
+ reachBottom:false,
+ readingTimer:null,
+ readTime:500,
+
+ tiems:5,
+ timer:null, // 倒计时
+ }
+ },
+
+ created() {
+ const _this = this;
+
+ // 多协议
+ if(this.getPlatformProtocolNewList.length){
+
+ const cache = uni.getStorageSync('protocol_read_cache') || {};
+
+ this.list = this.getPlatformProtocolNewList.map((item, index) => ({
+ ...item,
+ // isRead: cache[index]?.isRead || false
+ isRead: false
+ }));
+
+ this.ing = cache.ing || 0;
+
+ this.updateCurrent();
+ this.checkAllRead();
+ return;
+ }
+
+ // 单协议
+ uni.request({
+ url: this.$webHost + `/api/v2/protocolInfo/getProtocol?appId=xxx&code=${this.code}`,
+ success: (res) => {
+ _this.text = res.data.data.content;
+ _this.titleText = res.data.data.name;
+ _this.flag = false;
+ }
+ })
+ },
+
+ methods:{
+ open(){
+ this.$refs.boxCnt.open();
+ this.startCountDown();
+ },
+
+ closePopup() {
+ this.$refs.boxCnt.close()
+ },
+
+ // ✅ 倒计时
+ startCountDown(){
+ this.tiems = 5;
+
+ if(this.timer){
+ clearInterval(this.timer);
+ }
+
+ this.timer = setInterval(() => {
+ if(this.tiems > 0){
+ this.tiems--;
+ }else{
+ clearInterval(this.timer);
+ this.timer = null;
+ }
+ },1000);
+ },
+
+ // 更新当前协议
+ updateCurrent(){
+ this.text = this.list[this.ing].content;
+ this.titleText = this.list[this.ing].name;
+ this.scrollTop = 0;
+
+ this.reachBottom = false;
+
+ if(this.readingTimer){
+ clearTimeout(this.readingTimer);
+ }
+
+ // 每个协议重新倒计时
+ this.startCountDown();
+ },
+
+ // 滚动到底
+ scrolltolower(){
+ if(!this.list.length){
+ this.flag = true;
+ return;
+ }
+
+ if(this.reachBottom) return;
+
+ this.reachBottom = true;
+
+ if(this.readingTimer){
+ clearTimeout(this.readingTimer);
+ }
+
+ this.readingTimer = setTimeout(() => {
+
+ this.list[this.ing].isRead = true;
+
+ this.saveCache();
+
+ const allRead = this.list.every(item => item.isRead);
+
+ if (allRead) {
+ this.flag = true;
+ } else {
+
+ }
+
+ }, this.readTime);
+ },
+
+ // scroll 兜底
+ onScroll(e){
+ const { scrollTop, scrollHeight, deltaY } = e.detail;
+
+ if(scrollTop + deltaY >= scrollHeight - 100){
+ this.scrolltolower();
+ }
+ },
+
+ // 缓存
+ saveCache(){
+ const cache = {
+ ing: this.ing,
+ ...this.list.reduce((acc, item, index) => {
+ acc[index] = { isRead: item.isRead };
+ return acc;
+ }, {})
+ };
+
+ uni.setStorageSync('protocol_read_cache', cache);
+ },
+
+ // 判断是否全部读完
+ checkAllRead(){
+ this.flag = this.list.every(item => item.isRead);
+ },
+
+ // 点击确认
+ loadPopup(){
+ console.log(this.flag);
+ if(!this.flag){
+ if(this.getPlatformProtocolNewList.length && this.reachBottom){
+ if(this.readingTimer){
+ clearTimeout(this.readingTimer);
+ }
+ this.scrollTop = 0;
+
+ this.ing++;
+ if(this.ing === this.getPlatformProtocolNewList.length){
+ this.flag = true;
+
+ uni.removeStorageSync('protocol_read_cache');
+
+ this.$refs.boxCnt.close();
+ this.$emit('confirm');
+ return;
+ }
+ this.updateCurrent();
+ } else {
+ uni.showToast({
+ title: '请先阅读完本协议内容',
+ icon: 'none',
+ })
+ }
+
+ return;
+ }
+ if(!this.flag || this.tiems > 0) return;
+
+ uni.removeStorageSync('protocol_read_cache');
+
+ this.$refs.boxCnt.close();
+ this.$emit('confirm');
+ }
+ },
+
+ beforeDestroy(){
+ if(this.timer){
+ clearInterval(this.timer);
+ }
+ if(this.readingTimer){
+ clearTimeout(this.readingTimer);
+ }
+ }
+}
+</script>
+
+<template>
+ <uv-popup
+ ref="boxCnt"
+ z-index="999"
+ :round="16"
+ :safe-area-inset-bottom="true"
+ :closeOnClickOverlay="false"
+ >
+ <view class="box">
+
+ <!-- 标题 -->
+ <view class="title">
+ {{ titleText }}
+ </view>
+
+ <!-- 进度 -->
+ <view v-if="list.length" class="progress">
+ {{ ing + 1 }} / {{ list.length }}
+ </view>
+ <view v-if="!reachBottom" class="scroll-tip">
+ ↓ 请滑动阅读全部内容
+ </view>
+ <!-- 内容 -->
+ <scroll-view
+ :key="ing"
+ scroll-y
+ :scroll-top="scrollTop"
+ @scroll="onScroll"
+ @scrolltolower="scrolltolower"
+ lower-threshold="50"
+ style="height: 70vh;"
+ :show-scrollbar="true"
+ >
+ <view class="text-container">
+ <rich-text :nodes="text"></rich-text>
+ </view>
+ </scroll-view>
+
+ <!-- 按钮 -->
+ <view style="margin-top: 20rpx;">
+ <uv-button
+
+ :disabled="!flag || tiems > 0"
+ @click="loadPopup"
+ v-if="code"
+ :custom-style="{ color: '#FF1472',border:'none' }"
+ >
+ 确定
+ <text v-show="tiems">({{ tiems }}S)</text>
+ </uv-button>
+ <uv-button
+
+ :disabled="tiems > 0 || !reachBottom "
+ @click="loadPopup"
+ v-if="getPlatformProtocolNewList.length"
+ :custom-style="{ color: '#FF1472',border:'none' }"
+ >
+ {{ flag || getPlatformProtocolNewList.length === ing + 1 ? '确定' : '下一步' }}
+ <text v-show="tiems">({{ tiems }}S)</text>
+ </uv-button>
+ </view>
+
+ </view>
+ </uv-popup>
+</template>
+
+<style scoped lang="scss">
+.box{
+ padding: 40rpx;
+ width:80vw;
+ margin: auto;
+ border-radius: 40rpx;
+ background: white;
+}
+
+.title{
+ text-align: center;
+ font-weight: 800;
+ margin-bottom: 10rpx;
+ font-size: 34rpx;
+}
+
+.progress{
+ text-align: center;
+ font-size: 24rpx;
+ color: #999;
+ margin-bottom: 10rpx;
+}
+
+.text-container {
+ font-size: 28rpx;
+ line-height: 1.8;
+ color: #666;
+}
+.uni-scroll-view::-webkit-scrollbar {
+ width: 6px;
+}
+
+.uni-scroll-view::-webkit-scrollbar-thumb {
+ background: rgba(0,0,0,0.3);
+ border-radius: 10px;
+}
+
+.uni-scroll-view::-webkit-scrollbar-track {
+ background: transparent;
+}
+.scroll-tip{
+ text-align:center;
+ color:#999;
+ font-size:24rpx;
+ margin:10rpx 0;
+}
+</style>
\ No newline at end of file
--
Gitblit v1.9.3