Browse Source

fix: 修复答题流程时间bug

huangziyang 1 day ago
parent
commit
dc401c24c8

+ 47 - 32
components/Container/Container.vue

@@ -1,10 +1,10 @@
 <script setup>
 import Empty from "../Empty/Empty.vue";
-import pages from "@/pages.json";
 import { ref, onMounted, watchEffect } from "vue";
-import { getRoute, router } from "../../utils/router";
+import { router, getRoute } from "../../utils/router";
 import { getRect, debounce } from "../../utils";
 import { getCurrentInstance } from "vue";
+import pages from "@/pages.json";
 
 const props = defineProps({
   showBottom: {
@@ -93,7 +93,21 @@ const safeArea = ref({
 });
 const footerHeight = ref(0);
 
+const menuButtonInfo = ref({
+  top: 0,
+  height: 0,
+  width: 0,
+});
+
 onMounted(() => {
+  const _menuButtonInfo = uni.getMenuButtonBoundingClientRect();
+
+  menuButtonInfo.value = {
+    top: _menuButtonInfo.top,
+    height: _menuButtonInfo.height,
+    width: _menuButtonInfo.width,
+  };
+
   const systemInfo = uni.getWindowInfo();
   // 判断是否为tabbar页面
   safeArea.value = {
@@ -103,19 +117,24 @@ onMounted(() => {
 
   // 解决部分安卓手机安全顶部为0 的bug
   if (!safeArea.value.top) {
-    safeArea.value.top = systemInfo.statusBarHeight || 40;
+    safeArea.value.top = systemInfo.statusBarHeight;
   }
 
   const isTarbarPage = pages.tabBar.list
     .map((item) => item.pagePath)
     .includes(getRoute().routeList[0].path);
 
-  if (isTarbarPage) {
-    // 高度再减掉tabbar高度
-    safeArea.value.height -= 48;
+  if (
+    safeArea.value.source.bottom === safeArea.value.source.height &&
+    isTarbarPage
+  ) {
+    safeArea.value.height -= 50;
+  }
+
+  if (props.scrollStyle?.padding === void 0) {
+    // 24是内边距
+    safeArea.value.width -= 24;
   }
-  // 24是内边距
-  safeArea.value.width -= 24;
 
   const instance = getCurrentInstance();
   // 获取头部高度
@@ -123,9 +142,7 @@ onMounted(() => {
     name: ".title",
     onSuccess(res) {
       safeArea.value.title = res;
-      safeArea.value.height -= props.showTitle
-        ? safeArea.value.title?.height
-        : 0;
+      console.log(safeArea.value.title);
     },
     instance,
   });
@@ -133,11 +150,7 @@ onMounted(() => {
   getRect({
     name: ".bottom-button",
     onSuccess(res) {
-      console.log(res);
-
       safeArea.value.footer = res;
-      safeArea.value.height -= safeArea.value.footer?.height;
-      safeArea.value.height += 22; // 剩余高度
     },
     instance,
   });
@@ -180,7 +193,7 @@ defineExpose({
     </view>
     <scroll-view
       enable-flex
-      show-scrollbar
+      :show-scrollbar="false"
       enable-back-to-top
       scroll-with-animation
       scroll-anchoring
@@ -188,18 +201,19 @@ defineExpose({
       :scroll-y="scrollY"
       :scroll-top="scrollTop"
       @scroll="onScroll"
+      :class="['scroll-view', scrollX ? 'topic-scroll' : '']"
+      :style="{
+        height: `calc(${
+          safeArea.height - safeArea.top - safeArea.title?.height - 100
+        }px - env(safe-area-inset-bottom))`,
+        width: safeArea.width + 'px',
+        whiteSpace: scrollX ? 'nowrap' : 'normal',
+        flex: 1,
+        ...scrollStyle,
+      }"
       v-if="!empty"
     >
-      <view
-        :class="['scroll-view', scrollX ? 'topic-scroll' : '']"
-        :style="{
-          height: `${safeArea.height}px`,
-          whiteSpace: scrollX ? 'nowrap' : 'normal',
-          ...scrollStyle,
-        }"
-      >
-        <slot></slot>
-      </view>
+      <slot></slot>
       <!-- 底部文字 -->
       <view v-if="showBottom && bottomText" class="bottom-text">
         {{ bottomText }}
@@ -225,7 +239,11 @@ defineExpose({
 
 <style lang="scss" scoped>
 @import "@/uni.scss";
-
+scroll-view ::-webkit-scrollbar {
+  width: 0;
+  height: 0;
+  background-color: transparent;
+}
 .title {
   position: sticky;
   top: 0;
@@ -245,7 +263,7 @@ defineExpose({
 }
 
 .container {
-  display: gird;
+  display: flex;
   flex-direction: column;
   color: #333;
   box-sizing: content-box;
@@ -256,11 +274,8 @@ defineExpose({
 
 .scroll-view {
   position: relative;
-  padding: 24rpx 24rpx 0;
+  padding: 24rpx;
   box-sizing: content-box;
-  display: flex;
-  flex-direction: column;
-  gap: 24rpx;
 }
 
 .bottom-text {

+ 5 - 19
components/Topic/TopicExam.vue

@@ -27,12 +27,7 @@
             第{{ nowIndex + 1 }}题/共{{ total }}题
           </view>
         </view>
-        <uni-countdown
-          :show-day="false"
-          :hour="formatTime(Time.time.startTime, 'hour')"
-          :minute="formatTime(Time.time.startTime, 'minute')"
-          :second="formatTime(Time.time.startTime, 'second')"
-        />
+        <uni-countdown :show-day="false" :hour="1" :minute="30" :second="0" />
       </view>
       <template v-for="(item, parindex) in data" :key="parindex">
         <template v-if="parindex === nowIndex">
@@ -57,6 +52,9 @@
               v-else
               :nodes="item.questions_ex"
               class="question-text"
+              :style="{
+                lineHeight: 2,
+              }"
             ></rich-text>
             <questions
               v-if="item.style !== 6"
@@ -238,19 +236,6 @@ const submit = () => {
     open.value = true;
   }
 };
-const formatTime = (time, type) => {
-  // 获取time一个半小时后的时间戳
-  const timeStamp = new Date(time + 1.5 * 60 * 60 * 1000);
-  const date = new Date();
-  switch (type) {
-    case "hour":
-      return timeStamp.getHours() - date.getHours();
-    case "minute":
-      return timeStamp.getMinutes() - date.getMinutes();
-    case "second":
-      return timeStamp.getSeconds() - date.getSeconds();
-  }
-};
 
 const submitter = ref({
   text: "继续考试",
@@ -395,6 +380,7 @@ const onSafeAreaChange = (s) => {
 .other {
   display: flex;
   gap: 12px;
+  margin-top: 20rpx;
 }
 .scroll-view {
   height: 50vh;

+ 3 - 2
components/Topic/TopicPractice.vue

@@ -148,13 +148,14 @@
             >
               查看报告
             </view>
-            <view
+            <button
+              :disabled="!item.selectAns.length"
               class="button"
               v-if="!item.showResult"
               @click="questionSubmit(item, parindex)"
             >
               提交
-            </view>
+            </button>
           </view>
         </template>
       </template>

+ 2 - 2
components/Tree/Tree.vue

@@ -68,9 +68,9 @@ const emit = defineEmits(["onChnage", "onClickButton"]);
             >继续学习</view
           >
           <view
-            @click="emit('onClickButton', items)"
+            @click="emit('onClickButton', items, true)"
             class="comment"
-            v-if="items[keys.process] === 4"
+            v-if="items[keys.process] === 3"
             >去练习</view
           >
           <view

+ 7 - 0
pages.json

@@ -21,6 +21,13 @@
         "navigationBarTitleText": "挑战"
       }
     },
+    {
+      "path": "pages/challenge/rule",
+      "style": {
+        "navigationStyle": "custom",
+        "navigationBarTitleText": "规则"
+      }
+    },
     {
       "path": "pages/challenge/addContant",
       "style": {

+ 22 - 1
pages/challenge/index.vue

@@ -7,7 +7,9 @@
     :showBack="false"
   >
     <view>
-      <view class="bg"></view>
+      <view class="bg">
+        <div class="setting" @click="toRule">规则</div>
+      </view>
     </view>
     <template #stick>
       <button class="btn" @click="toAdd">立即报名!参与挑战!</button>
@@ -43,6 +45,12 @@ onShow(async () => {
   });
 });
 
+const toRule = () => {
+  router.push({
+    url: "/pages/challenge/rule",
+  });
+};
+
 const toAdd = async () => {
   if (isPay.value) {
     router.push({
@@ -100,6 +108,19 @@ const toAdd = async () => {
   background-size: cover;
   padding: 32rpx;
   box-sizing: border-box;
+  position: relative;
+
+  .setting {
+    position: absolute;
+    right: 0;
+    top: 200rpx;
+    background: rgba(0, 0, 0, 0.5);
+    border-radius: 500rpx 0rpx 0rpx 500rpx;
+    font-weight: 500;
+    font-size: 24rpx;
+    color: #ffffff;
+    padding: 8rpx;
+  }
 }
 
 .btn {

+ 7 - 0
pages/challenge/rule.vue

@@ -0,0 +1,7 @@
+<script setup>
+import Container from "../../components/Container/Container.vue";
+</script>
+<template>
+  <Container title="规则"> </Container>
+</template>
+<style scoped lang="scss"></style>

+ 7 - 3
pages/real/exam.vue

@@ -20,6 +20,7 @@ const correct = ref({
   not: 0, // 未答题
   total: 0, // 总题数
 });
+const useTime = ref(null);
 
 const showReport = ref(false);
 const showShare = ref(false);
@@ -103,9 +104,8 @@ const getList = async (params = {}) => {
       };
     })
   );
-  console.log(data.value);
-
   if (catalogue_id) {
+    useTime.value = res.data.use_time_str;
     lookReport(data.value, submitter.value);
   }
 };
@@ -185,7 +185,11 @@ onMounted(async () => {
       <div class="title-r">恭 喜 完 成 本 课</div>
       <view class="card">
         <view class="card-time">
-          <view>{{ submitter.totalTime?.formatTime }}</view>
+          <view>{{
+            useTime !== null
+              ? useTime
+              : submitter.totalTime?.formatTime
+          }}</view>
           <view>学习时长</view>
         </view>
         <view class="card-time">

+ 1 - 2
pages/real/history.vue

@@ -44,7 +44,7 @@
           "
         >
           <view>{{ util.timestampToString_day(item.begin_time) }}</view>
-          <view>{{ item.use_time_str?.split(":")?.[0] }}分钟</view>
+          <view>{{ item.use_time }}分钟</view>
           <view>{{ item.complete }}/100题</view>
           <view class="score"
             >{{ item.score }}分<uni-icons type="right"
@@ -71,7 +71,6 @@ const userInfo = ref({
   username: "Hi, 这里是历史题库",
 });
 const list = ref([]);
-
 const onClick = (data = {}) => {
   router.push({
     url: "/pages/real/exam",

+ 1 - 0
pages/real/index.vue

@@ -119,6 +119,7 @@ onShow(async () => {
   width: 214rpx;
   height: 282rpx;
   background: url("https://openwork-oss.oss-cn-shenzhen.aliyuncs.com/uploads/question/2025/05/mrgkegM1h3pgz5taDRfQv5r1DX4DfONhIJtgJXEv.png");
+  background-size: 100% 100%;
   .text {
     margin-top: 32rpx;
     margin-left: 54rpx;

+ 16 - 31
pages/regulations/index.vue

@@ -12,20 +12,11 @@
       v-show="!showContainer"
     >
       <view class="free-content">
-        <uni-collapse-item
-          :title="item.name"
-          v-for="item in freeChaptersList"
-          :key="item.id"
-          class="text"
-        >
-          <view class="-mt-20">
-            <Tree
-              :chaptersList="item.children"
-              @onChnage="onChnage"
-              @onClickButton="onClickButton"
-            />
-          </view>
-        </uni-collapse-item>
+        <Tree
+          :chaptersList="freeChaptersList"
+          @onChnage="onChnage"
+          @onClickButton="onClickButton"
+        />
       </view>
       <!-- 付费功能 -->
       <view class="pay-content" v-if="chaptersList.length">
@@ -42,20 +33,11 @@
           </view>
           <view class="modal-wrapper" @click="onClickMask">邀请好友可解锁</view>
         </view>
-        <uni-collapse-item
-          :title="item.name"
-          v-for="item in chaptersList"
-          :key="item.id"
-          class="text"
-        >
-          <view class="-mt-20">
-            <Tree
-              :chaptersList="item.children"
-              @onChnage="onChnage"
-              @onClickButton="onClickButton"
-            />
-          </view>
-        </uni-collapse-item>
+        <Tree
+          :chaptersList="chaptersList"
+          @onChnage="onChnage"
+          @onClickButton="onClickButton"
+        />
       </view>
     </uni-collapse>
     <Modal
@@ -99,15 +81,17 @@ const chaptersList = ref([]);
 const freeChaptersList = ref([]);
 
 // 点击学习按钮
-const onClickButton = (item) => {
+const onClickButton = (item, practice) => {
   console.log(item);
-
   router.push({
-    url: "/pages/regulations/learing",
+    url: practice
+      ? "/pages/regulations/practice"
+      : "/pages/regulations/learing",
     params: {
       id: item.id,
       parent_id: item.parent_id,
       name: item.name,
+      title: item.name,
     },
   });
 };
@@ -158,6 +142,7 @@ onShow(async () => {
   // 付费章节
   chaptersList.value = payList;
   title.value = getRoute().params.title;
+  console.log(freeList);
 });
 </script>
 

+ 16 - 7
pages/regulations/learing.vue

@@ -37,6 +37,7 @@ const onScroll = (e) => {
   scrollTop.value = e.detail.scrollTop;
 };
 const submitScrollTop = (is_done, scroll) => {
+  if (otherParams.value.is_done) return;
   request(
     "api/question_bank/question_reception/point/set_point_study_progress",
     {
@@ -78,14 +79,17 @@ onShow(() => {
       };
     });
     otherParams.value = data;
-    // scrollTop.value = data.scroll_top;
   });
 });
+
+const onClick = (e, index) => {
+  scrollTop.value = e.currentTarget.offsetTop
+};
 </script>
 
 <template>
   <Container
-    title="法规"
+    :title="getRoute().params?.name"
     @onScroll="onScroll"
     :empty="!context.length"
     :scrollTop="scrollTop"
@@ -97,7 +101,9 @@ onShow(() => {
           class="title"
           :class="{
             'mt-40': index !== 0,
+            [`title-${index}`]: true,
           }"
+          @click="(e) => onClick(e, index)"
           >考 点{{ index + 1 }} {{ item.name }}</view
         >
         <uv-parse class="text" :content="item.context" selectable />
@@ -112,12 +118,15 @@ onShow(() => {
   color: #703060;
   font-weight: bold;
   text-align: center;
-  margin: 28rpx 0;
+  padding: 30rpx 0;
   font-size: 40rpx;
-}
-
-.mt-40 {
-  margin-top: 80rpx;
+  // position: sticky;
+  top: 0;
+  background-color: #fff;
+  z-index: 999;
+  display: flex;
+  align-items: center;
+  justify-content: center;
 }
 
 .text {