Bläddra i källkod

Merge branch 'master' of http://47.112.106.152:10880/Saas/exam_mp

huangziyang 1 vecka sedan
förälder
incheckning
19bdf22c2a
1 ändrade filer med 288 tillägg och 268 borttagningar
  1. 288 268
      pages/index/index.vue

+ 288 - 268
pages/index/index.vue

@@ -1,323 +1,343 @@
 <template>
-  <Container
-    class="body-content"
-    title="首页"
-    bgColor="#F8F8F8"
-    :showBack="false"
-  >
-    <view class="home">
-      <!-- 倒计时 -->
-      <view class="time">
-        <view>倒计时</view>
-        <view class="tiem-item">1</view>
-        <view class="tiem-item">0</view>
-        <view class="tiem-item">0</view>
-        <view>天</view>
-      </view>
-      <!-- 轮播图 -->
-      <swiper class="swiper" circular autoplay>
-        <swiper-item v-for="(item, index) in banner_list" :key="index">
-          <view class="swiper-item"
-            ><image
-              class="swiper-item-image"
-              :src="item.image_url"
-              mode="aspectFill"
-              @load="onImageLoad($event, item, index)"
-            ></image
-          ></view>
-        </swiper-item>
-      </swiper>
-      <!-- 公告 -->
-      <view class="notice" v-if="notice_list != '' && notice_list != null">
-        <view class="title-lable">公告</view>
-        <view class="notice-title">{{ notice_list[0]["title"] }}</view>
-        <navigator url="/pages/notice/list">
-          <view class="notice-more">{{ "更多 >" }}</view>
-        </navigator>
-      </view>
-      <!-- 2025新大纲 -->
-      <view class="new_outline">
-        <uni-section title="基础用法" type="line">
-          <view class="p-20">
-            <uni-segmented-control
-              :flex="false"
-              :current="current"
-              :values="list.map((item) => item.name)"
-              style-type="text"
-              @clickItem="(e) => (current = e.currentIndex)"
-            />
-            <!-- 执业药师 -->
-            <template v-for="(item, index) in list" :key="item.id">
-              <view v-if="current === index" class="grid">
-                <view
-                  v-for="i in item?.children"
-                  class="flex"
-                  @click="clickClass(i)"
-                >
-                  <image :src="i.chapter_image_url" class="img_small"></image>
-                  <view>{{ i.name }}</view>
-                </view>
-              </view>
-            </template>
-          </view>
-        </uni-section>
-      </view>
-      <view class="p-20">
-        <uni-section title="往年真题" type="line">
-          <!-- 往年真题 -->
-          <view class="grid-3">
-            <view
-              v-for="item in 7"
-              class="flex"
-              @click="
-                toReal({
-                  title: '2025真题',
-                })
-              "
-            >
-              <view class="bg-red">
-                <view class="text">执业药师{{ item }}</view>
-              </view>
-            </view>
-          </view>
-        </uni-section>
-      </view>
-    </view>
-  </Container>
+	<Container class="body-content" title="首页" bgColor="#F8F8F8" :showBack="false">
+		<view class="home">
+			<!-- 倒计时 -->
+			<view class="time" v-if="(splitDays != '') & (splitDays != null)">
+				<view>倒计时</view>
+				<!-- 将天数拆分为单个数字显示 -->
+				<view class="exam-countdown-tiem-item" v-for="(digit, index) in splitDays" :key="index">{{ digit }}</view>
+				<view>天</view>
+			</view>
+			<!-- 轮播图 -->
+			<swiper class="swiper" circular autoplay>
+				<swiper-item v-for="(item, index) in banner_list" :key="index">
+					<view class="swiper-item"><image class="swiper-item-image" :src="item.image_url" mode="aspectFill" @load="onImageLoad($event, item, index)" @click="goto_notice_list(item.link_url)"></image></view>
+				</swiper-item>
+			</swiper>
+			<!-- 公告 -->
+			<view class="notice" v-if="notice_list != '' && notice_list != null">
+				<view class="title-lable">公告</view>
+				<view class="notice-title">{{ notice_list[0]['title'] }}</view>
+				<navigator url="/pages/notice/list">
+					<view class="notice-more">{{ '更多 >' }}</view>
+				</navigator>
+			</view>
+			<!-- 2025新大纲 -->
+			<view class="new_outline">
+				<uni-section title="基础用法" type="line">
+					<view class="p-20">
+						<uni-segmented-control
+							:flex="false"
+							:current="current"
+							:values="list.map((item) => item.name)"
+							style-type="text"
+							@clickItem="(e) => (current = e.currentIndex)"
+						/>
+						<!-- 执业药师 -->
+						<template v-for="(item, index) in list" :key="item.id">
+							<view v-if="current === index" class="grid">
+								<view v-for="i in item?.children" class="flex" @click="clickClass(i)">
+									<image :src="i.chapter_image_url" class="img_small"></image>
+									<view>{{ i.name }}</view>
+								</view>
+							</view>
+						</template>
+					</view>
+				</uni-section>
+			</view>
+			<view class="p-20">
+				<uni-section title="往年真题" type="line">
+					<!-- 往年真题 -->
+					<view class="grid-3">
+						<view
+							v-for="item in 7"
+							class="flex"
+							@click="
+								toReal({
+									title: '2025真题'
+								})
+							"
+						>
+							<view class="bg-red">
+								<view class="text">执业药师{{ item }}</view>
+							</view>
+						</view>
+					</view>
+				</uni-section>
+			</view>
+		</view>
+	</Container>
 </template>
 
 <script setup>
-import { ref, onMounted } from "vue";
+import { ref, onMounted, computed, onBeforeUnmount } from 'vue';
 
-import Container from "../../components/Container/Container.vue";
-import { router } from "../../utils/router";
-import { request } from "../../utils/request";
-import { arrayToTree } from "../../utils";
+import Container from '../../components/Container/Container.vue';
+import { router } from '../../utils/router';
+import { request } from '../../utils/request';
+import { arrayToTree } from '../../utils';
 
 const current = ref(0);
 const list = ref([]);
 const banner_list = ref([]);
 const notice_list = ref([]);
-const imgHeight = ref("auto"); // 初始高度
+const imgHeight = ref('auto'); // 初始高度
+
+const days = ref('000'); // 默认值设为100,确保有3位数
+let timer = null;
+const exam_time=ref(''); //考试时间
+
+// 将天数拆分为单个数字数组
+const splitDays = computed(() => {
+	// 将数字转为字符串,然后拆分为字符数组
+	const str = days.value.toString();
+	// 如果不足3位数,前面补0(例如5变成["0","0","5"])
+	return str.padStart(3, '0').split('');
+});
+
+const calculateDays = () => {
+	// const targetDate = new Date('2025-12-31');
+	const targetDate = new Date(Number(exam_time.value*1000))
+	const currentDate = new Date();
+	const diffTime = targetDate - currentDate;
+	const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
+	days.value = diffDays > 0 ? diffDays : 0;
+};
 
 const clickClass = ({ id }) => {
-  router.push({
-    url: "/pages/regulations/index",
-    params: {
-      id,
-    },
-  });
+	router.push({
+		url: '/pages/regulations/index',
+		params: {
+			id
+		}
+	});
 };
 
 const toReal = (item) => {
-  router.push({
-    url: "/pages/real/index",
-    params: item,
-  });
+	router.push({
+		url: '/pages/real/index',
+		params: item
+	});
 };
 const onImageLoad = (e, item, index) => {
-  const { width, height } = e.detail;
-  const ratio = height / width;
-  const systemInfo = uni.getSystemInfoSync();
-  const imgHeightValue = systemInfo.windowWidth * ratio;
-  imgHeight.value = imgHeightValue + "px";
+	const { width, height } = e.detail;
+	const ratio = height / width;
+	const systemInfo = uni.getSystemInfoSync();
+	const imgHeightValue = systemInfo.windowWidth * ratio;
+	imgHeight.value = imgHeightValue + 'px';
+};
+onBeforeUnmount(() => {
+	if (timer) clearInterval(timer);
+});
+const goto_notice_list=(link_url)=>{
+	uni.navigateTo({
+		url:link_url
+	});
 };
 onMounted(async () => {
-  const res = await request(
-    "api/question_bank/question_reception/chapter/get",
-    {},
-    "POST"
-  );
-  list.value = arrayToTree({
-    list: res.data,
-  });
+	const res = await request('api/question_bank/question_reception/chapter/get', {}, 'POST');
+	list.value = arrayToTree({
+		list: res.data
+	});
+	// 首页轮播
+	const banner_res = await request('api/question_bank/question_reception/banner/list', { page: 1, limit: 10 }, 'POST');
+	banner_list.value = banner_res.data.data;
+	//系统公告
+	const notice_res = await request('api/question_bank/question_reception/notice/list', { page: 1, limit: 1 }, 'POST');
+	notice_list.value = notice_res.data.data;
+	//获取考试倒计时
+	const examination_res = await request('api/question_bank/question_reception/common_config/detail', { content_code: 'examination_countdown' }, 'POST');
+	exam_time.value=examination_res !='' ? examination_res.data.content_detail:'';
 
-  console.log(list.value);
-
-  // 首页轮播
-  const banner_res = await request(
-    "api/question_bank/question_reception/banner/list",
-    { page: 1, limit: 10 },
-    "POST"
-  );
-  banner_list.value = banner_res.data.data;
-  //系统公告
-  const notice_res = await request(
-    "api/question_bank/question_reception/notice/list",
-    { page: 1, limit: 1 },
-    "POST"
-  );
-  notice_list.value = notice_res.data.data;
-  console.log(notice_list);
+	calculateDays();
+	timer = setInterval(() => {
+		calculateDays();
+	}, 24 * 60 * 60 * 1000);
+	return {
+		days,
+		splitDays
+	};
 });
 </script>
 
 <style scoped lang="scss">
-@import "@/uni.scss";
+@import '@/uni.scss';
 .img_small {
-  width: 112rpx;
-  height: 112rpx;
+	width: 112rpx;
+	height: 112rpx;
 }
 .body-content {
-  background: #f8f8f8;
-  border-radius: 0rpx 0rpx 0rpx 0rpx;
+	background: #f8f8f8;
+	border-radius: 0rpx 0rpx 0rpx 0rpx;
+}
+.exam-countdown-tiem-item {
+	width: 24rpx;
+	height: 34rpx;
+	background: #ff3c3c;
+	border-radius: 2rpx 2rpx 2rpx 2rpx;
+	font-family: PingFang SC, PingFang SC;
+	font-weight: 500;
+	font-size: 24rpx;
+	color: #ffffff;
+	display: flex;
+	align-items: center;
+	justify-content: center;
 }
 .home {
-  display: flex;
-  flex-direction: column;
-  gap: 20rpx;
+	display: flex;
+	flex-direction: column;
+	gap: 20rpx;
 
-  .time {
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    font-family: PingFang SC, PingFang SC;
-    font-weight: 500;
-    font-size: 24rpx;
-    color: #333333;
-    gap: 8rpx;
+	.time {
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		font-family: PingFang SC, PingFang SC;
+		font-weight: 500;
+		font-size: 24rpx;
+		color: #333333;
+		gap: 8rpx;
 
-    .tiem-item {
-      width: 24rpx;
-      height: 34rpx;
-      background: #ff3c3c;
-      border-radius: 2rpx 2rpx 2rpx 2rpx;
-      font-family: PingFang SC, PingFang SC;
-      font-weight: 500;
-      font-size: 24rpx;
-      color: #ffffff;
-      display: flex;
-      align-items: center;
-      justify-content: center;
-    }
-  }
+		.tiem-item {
+			width: 24rpx;
+			height: 34rpx;
+			background: #ff3c3c;
+			border-radius: 2rpx 2rpx 2rpx 2rpx;
+			font-family: PingFang SC, PingFang SC;
+			font-weight: 500;
+			font-size: 24rpx;
+			color: #ffffff;
+			display: flex;
+			align-items: center;
+			justify-content: center;
+		}
+	}
 
-  .swiper {
-    width: 100%;
-    height: v-bind(imgHeight);
-    /* 关键修复样式 */
-    overflow: hidden;
-    transform-style: preserve-3d;
+	.swiper {
+		width: 100%;
+		height: v-bind(imgHeight);
+		/* 关键修复样式 */
+		overflow: hidden;
+		transform-style: preserve-3d;
 
-    .swiper-item {
-      width: 100%;
-      height: 100%;
-      overflow: hidden;
-      border-radius: 30rpx;
-      /* 确保变换不影响子元素 */
-      transform: translateZ(0);
+		.swiper-item {
+			width: 100%;
+			height: 100%;
+			overflow: hidden;
+			border-radius: 30rpx;
+			/* 确保变换不影响子元素 */
+			transform: translateZ(0);
 
-      .swiper-item-image {
-        width: 100%;
-        height: 100%;
-        display: block;
-        border-radius: 30rpx;
-        /* 防止图片变形 */
-        object-fit: cover;
-        /* 确保层级 */
-        position: relative;
-      }
-    }
-  }
+			.swiper-item-image {
+				width: 100%;
+				height: 100%;
+				display: block;
+				border-radius: 30rpx;
+				/* 防止图片变形 */
+				object-fit: cover;
+				/* 确保层级 */
+				position: relative;
+			}
+		}
+	}
 
-  .notice {
-    display: flex;
-    align-items: center;
-    gap: 20rpx;
-    padding-left: 26rpx;
-    height: 72rpx;
-    background: #ffffff;
-    border-radius: 500rpx 500rpx 500rpx 500rpx;
-    border: 1rpx solid #f8f8f8;
-    .title-lable {
-      padding: 5rpx 15rpx;
-      border-radius: 8rpx 8rpx 8rpx 8rpx;
-      border: 1rpx solid #3f75ff;
-      font-weight: 500;
-      font-size: 26rpx;
-      color: #3f75ff;
-      line-height: 32rpx;
-      text-align: center;
-      font-style: normal;
-      text-transform: none;
-    }
-    .notice-title {
-      width: calc(100% - 225rpx);
-      color: #333;
-      font-size: 26rpx;
-      display: -webkit-box;
-      -webkit-box-orient: vertical;
-      -webkit-line-clamp: 1;
-      overflow: hidden;
-      text-overflow: ellipsis;
-    }
-    .notice-more {
-      font-size: 26rpx;
-    }
-  }
+	.notice {
+		display: flex;
+		align-items: center;
+		gap: 20rpx;
+		padding-left: 26rpx;
+		height: 72rpx;
+		background: #ffffff;
+		border-radius: 500rpx 500rpx 500rpx 500rpx;
+		border: 1rpx solid #f8f8f8;
+		.title-lable {
+			padding: 5rpx 15rpx;
+			border-radius: 8rpx 8rpx 8rpx 8rpx;
+			border: 1rpx solid #3f75ff;
+			font-weight: 500;
+			font-size: 26rpx;
+			color: #3f75ff;
+			line-height: 32rpx;
+			text-align: center;
+			font-style: normal;
+			text-transform: none;
+		}
+		.notice-title {
+			width: calc(100% - 225rpx);
+			color: #333;
+			font-size: 26rpx;
+			display: -webkit-box;
+			-webkit-box-orient: vertical;
+			-webkit-line-clamp: 1;
+			overflow: hidden;
+			text-overflow: ellipsis;
+		}
+		.notice-more {
+			font-size: 26rpx;
+		}
+	}
 }
 
 .title {
-  font-family: "PingFang SC, PingFang SC";
-  font-weight: 700;
-  font-size: 32rpx;
-  color: #000000;
+	font-family: 'PingFang SC, PingFang SC';
+	font-weight: 700;
+	font-size: 32rpx;
+	color: #000000;
 }
 
 .p-20 {
-  display: flex;
-  flex-direction: column;
-  gap: 20rpx;
+	display: flex;
+	flex-direction: column;
+	gap: 20rpx;
 }
 
 .grid {
-  display: grid;
-  grid-template-columns: repeat(4, 1fr);
-  background-color: #ffffff;
-  padding: 24rpx;
-  gap: 16rpx;
-  border-radius: 16rpx;
+	display: grid;
+	grid-template-columns: repeat(4, 1fr);
+	background-color: #ffffff;
+	padding: 24rpx;
+	gap: 16rpx;
+	border-radius: 16rpx;
 }
 
 .grid-3 {
-  display: grid;
-  grid-template-columns: repeat(3, 1fr);
-  background-color: #ffffff;
-  padding: 24rpx;
-  gap: 16rpx;
-  border-radius: 16rpx;
-  height: 100%;
+	display: grid;
+	grid-template-columns: repeat(3, 1fr);
+	background-color: #ffffff;
+	padding: 24rpx;
+	gap: 16rpx;
+	border-radius: 16rpx;
+	height: 100%;
 }
 
 .flex {
-  display: flex;
-  flex-direction: column;
-  gap: 20rpx;
-  align-items: center;
-  justify-content: center;
+	display: flex;
+	flex-direction: column;
+	gap: 20rpx;
+	align-items: center;
+	justify-content: center;
 }
 
 .bg-red {
-  width: 191.07rpx;
-  height: 179.61rpx;
-  background: url("https://openwork-oss.oss-cn-shenzhen.aliyuncs.com/uploads/question/2025/05/WmhlbORF2q8A62Ytg1RVac8AYSGPkf7F2pEY6jQP.png")
-    no-repeat;
-  background-size: cover;
-  display: flex;
-  justify-content: center;
+	width: 191.07rpx;
+	height: 179.61rpx;
+	background: url('https://openwork-oss.oss-cn-shenzhen.aliyuncs.com/uploads/question/2025/05/WmhlbORF2q8A62Ytg1RVac8AYSGPkf7F2pEY6jQP.png') no-repeat;
+	background-size: cover;
+	display: flex;
+	justify-content: center;
 
-  .text {
-    font-family: jiangxizhuokai, jiangxizhuokai;
-    font-weight: bold;
-    font-size: 27rpx;
-    color: #3f75ff;
-    text-shadow: 0px 2px 4px #bdcfff;
-    text-align: left;
-    font-style: normal;
-    text-transform: none;
-    margin-top: 16rpx;
-    width: 95rpx;
-    height: 70rpx;
-  }
+	.text {
+		font-family: jiangxizhuokai, jiangxizhuokai;
+		font-weight: bold;
+		font-size: 27rpx;
+		color: #3f75ff;
+		text-shadow: 0px 2px 4px #bdcfff;
+		text-align: left;
+		font-style: normal;
+		text-transform: none;
+		margin-top: 16rpx;
+		width: 95rpx;
+		height: 70rpx;
+	}
 }
-</style>
+</style>