Browse Source

更新ui和联调接口

aamin 1 year ago
parent
commit
ef54609023
41 changed files with 1769 additions and 894 deletions
  1. 3 0
      components.d.ts
  2. 5 9
      src/App.vue
  3. 4 2
      src/api/api/activeBooking/index.ts
  4. 1 1
      src/api/api/artwork/index.ts
  5. 2 1
      src/api/api/dynamic/index.ts
  6. 3 2
      src/api/api/exhibition/index.ts
  7. 5 0
      src/api/api/sceneBooking/index.ts
  8. 1 1
      src/api/api/summarize/index.ts
  9. 3 1
      src/api/api/treasure/index.ts
  10. 3 1
      src/api/api/volunteerHome/index.ts
  11. 1 1
      src/api/request.ts
  12. BIN
      src/assets/fonts/SourceHanSansCN-Bold.ttf
  13. BIN
      src/assets/fonts/SourceHanSansCN-Medium.otf
  14. BIN
      src/assets/fonts/SourceHanSansCN-Regular.otf
  15. BIN
      src/assets/images/cicle.png
  16. BIN
      src/assets/images/left.png
  17. BIN
      src/assets/images/no-data.png
  18. BIN
      src/assets/images/onlineBg.png
  19. BIN
      src/assets/images/pause.png
  20. BIN
      src/assets/images/play.png
  21. BIN
      src/assets/images/right.png
  22. BIN
      src/assets/images/sceneBack.png
  23. BIN
      src/assets/images/search_icon.png
  24. 20 0
      src/components/IframePage/index.vue
  25. 61 0
      src/components/SearchInput/index.vue
  26. 91 99
      src/views/EnterNingguo/artwork.vue
  27. 61 42
      src/views/EnterNingguo/dynamic-detail.vue
  28. 158 23
      src/views/EnterNingguo/dynamic.vue
  29. 66 12
      src/views/EnterNingguo/summarize.vue
  30. 87 65
      src/views/ExhibitionService/active-detail.vue
  31. 142 25
      src/views/ExhibitionService/active-info.vue
  32. 162 98
      src/views/ExhibitionService/activeBooking.vue
  33. 6 0
      src/views/ExhibitionService/bookedList.vue
  34. 91 0
      src/views/ExhibitionService/components/BookingTime.vue
  35. 66 46
      src/views/SmartTour/exhibition-detail.vue
  36. 135 108
      src/views/SmartTour/exhibition.vue
  37. 71 35
      src/views/SmartTour/treasure-detail.vue
  38. 141 114
      src/views/SmartTour/treasure.vue
  39. 141 25
      src/views/VolunteerHome/apply.vue
  40. 81 99
      src/views/VolunteerHome/detail.vue
  41. 158 84
      src/views/VolunteerHome/home.vue

+ 3 - 0
components.d.ts

@@ -7,8 +7,11 @@ export {}
 
 declare module 'vue' {
   export interface GlobalComponents {
+    IframePage: typeof import('./src/components/IframePage/index.vue')['default']
+    NoData: typeof import('./src/components/NoData/index.vue')['default']
     RouterLink: typeof import('vue-router')['RouterLink']
     RouterView: typeof import('vue-router')['RouterView']
+    SearchInput: typeof import('./src/components/SearchInput/index.vue')['default']
     VanField: typeof import('vant/es')['Field']
     VanSearch: typeof import('vant/es')['Search']
     VanSwipe: typeof import('vant/es')['Swipe']

+ 5 - 9
src/App.vue

@@ -60,13 +60,13 @@ onBeforeMount(() => {
 
 <style scoped>
 @font-face {
-  font-family: 'REEJI-DuoguanGB-free-Flash';
-  src: url('./assets/fonts/REEJI-DuoguanGB-free-Flash.ttf');
+  font-family: 'SourceHanSansCN-Bold';
+  src: url('./assets/fonts/SourceHanSansCN-Bold.ttf');
 }
 
 @font-face {
-  font-family: 'SourceHanSansCN-Bold';
-  src: url('./assets/fonts/SourceHanSansCN-Bold.otf');
+  font-family: 'SourceHanSansCN-Regular';
+  src: url('./assets/fonts/SourceHanSansCN-Regular.otf');
 }
 
 @font-face {
@@ -74,16 +74,12 @@ onBeforeMount(() => {
   src: url('./assets/fonts/SourceHanSansCN-Medium.otf');
 }
 
-@font-face {
-  font-family: 'SourceHanSerifCN-Heavy';
-  src: url('./assets/fonts/SourceHanSerifCN-Heavy.otf');
-}
-
 
 
 #app {
   width: 100%;
   height: 100%;
+  background: #F7F3E8;
 }
 
 * {

+ 4 - 2
src/api/api/activeBooking/index.ts

@@ -1,5 +1,7 @@
 import axiosInstance from '@/api/request'
 export const ActiveBookingApi = {
-  getActiveList:() => axiosInstance.get(''),
-  getDetailById: (id: number) => axiosInstance.get(`${id}`)
+  getActiveList: (data: any) => axiosInstance.post('show/activity/pageList', data),
+  getDetailById: (id: number) => axiosInstance.get(`show/activity/detail/${id}`)
 }
+
+

+ 1 - 1
src/api/api/artwork/index.ts

@@ -1,4 +1,4 @@
 import axiosInstance from '@/api/request'
 export const ArtworkApi = {
-  getSearchByKeyword: (data: any) => axiosInstance.get('', data)
+  getSearchByKeyword: (data: any) => axiosInstance.post('show/cultural/pageList', data)
 }

+ 2 - 1
src/api/api/dynamic/index.ts

@@ -1,5 +1,6 @@
 import axiosInstance from '@/api/request'
 export const DynamicApi = {
-  getDynamicList:() => axiosInstance.get(''),
+  getDynamicList: (data: any) => axiosInstance.post('show/news/pageList', data),
   getDetailById: (id: number) => axiosInstance.get(`${id}`)
 }
+

+ 3 - 2
src/api/api/exhibition/index.ts

@@ -1,5 +1,6 @@
 import axiosInstance from '@/api/request'
 export const ExhibitionApi = {
-  getExhibitionList: () => axiosInstance.get(''),
-  getDetailById: (id: number) => axiosInstance.get(`${id}`,)
+  getExhibitionList: (data: any) => axiosInstance.post('show/exhibition/pageList', data),
+  getDetailById: (id: number) => axiosInstance.get(`show/exhibition/detail/${id}`)
 }
+

+ 5 - 0
src/api/api/sceneBooking/index.ts

@@ -0,0 +1,5 @@
+import axiosInstance from '@/api/request'
+export const sceneBookingApi = {
+  getDisableDateAPi: () => axiosInstance.get(''),
+  getBookingTimeAPI: () => axiosInstance.get('')
+}

+ 1 - 1
src/api/api/summarize/index.ts

@@ -2,5 +2,5 @@ import axiosInstance from '@/api/request'
 export const SummarizeApi = {
   // 获得概述内容
   // getSummerize: () => request('/wxShow/config/getAppreciate', 'GET', {})
-  getSummerize: () => axiosInstance.get('/wxShow/config/getAppreciate'),
+  getSummerize: () => axiosInstance.get('show/overview/detail'),
 }

+ 3 - 1
src/api/api/treasure/index.ts

@@ -1,4 +1,6 @@
 import axiosInstance from '@/api/request'
 export const TreasureApi = {
-  getTreasureList: () => axiosInstance.get(''),
+  getTypeList: () => axiosInstance.get('show/goods/getDict'),
+  getTreasureList: (data: any) => axiosInstance.post('show/goods/pageList', data),
+  getDetailById: (id: number) => axiosInstance.get(`show/goods/detail/${id}`)
 }

+ 3 - 1
src/api/api/volunteerHome/index.ts

@@ -1,4 +1,6 @@
 import axiosInstance from '@/api/request'
 export const VolunteerApi = {
-  getVolunteerList: () => axiosInstance.get(''),
+  getVolunteerList: (data: any) => axiosInstance.post('show/volunteer/pageList', data),
+  getDetailById: (id: number) => axiosInstance.get(`show/volunteer/detail/${id}`),
+  saveApplyAPI: (data: any) => axiosInstance.post('show/bookInfo/save', data)
 }

+ 1 - 1
src/api/request.ts

@@ -4,7 +4,7 @@ import axios from 'axios';
 //设置基地址
 // export const baseUrl = "https://wxfalangchang.4dage.com/api";
 // export const baseIMGUrl = "https://wxfalangchang.4dage.com";
-export const baseUrl = "";
+export const baseUrl = "http://192.168.20.61:8067/api/";
 export const baseIMGUrl = "";
 
 

BIN
src/assets/fonts/SourceHanSansCN-Bold.ttf


BIN
src/assets/fonts/SourceHanSansCN-Medium.otf


BIN
src/assets/fonts/SourceHanSansCN-Regular.otf


BIN
src/assets/images/cicle.png


BIN
src/assets/images/left.png


BIN
src/assets/images/no-data.png


BIN
src/assets/images/onlineBg.png


BIN
src/assets/images/pause.png


BIN
src/assets/images/play.png


BIN
src/assets/images/right.png


BIN
src/assets/images/sceneBack.png


BIN
src/assets/images/search_icon.png


+ 20 - 0
src/components/IframePage/index.vue

@@ -0,0 +1,20 @@
+<!-- eslint-disable vue/multi-word-component-names -->
+<script setup lang='ts'>
+const props = defineProps(['iframeLink'])
+const emit = defineEmits(['isShowIframeChange'])
+
+const isShowIframeChangeFu = () => {
+  emit('isShowIframeChange', false)
+}
+
+
+</script>
+
+<template>
+  <div class="iframe-box" >
+    <img src="@/assets/images/sceneBack.png" alt="" @click="isShowIframeChangeFu">
+    <iframe :src="props.iframeLink" frameborder="0"></iframe>
+  </div>
+</template>
+
+<style lang='less' scoped></style>

+ 61 - 0
src/components/SearchInput/index.vue

@@ -0,0 +1,61 @@
+<!-- eslint-disable vue/multi-word-component-names -->
+<script setup lang='ts'>
+
+const emit = defineEmits(['onSearch']);
+const isSearch = ref(false)
+const inputField = ref(null as any);
+const searchValue = ref('')
+const focusInput = () => {
+  setTimeout(() => {
+    if (inputField.value) {
+      console.log(inputField.value)
+      inputField.value.focus();
+    }
+  }, 200)
+}
+
+watch(searchValue, () => {
+  emit('onSearch', searchValue.value);
+})
+
+</script>
+
+<template>
+  <div class="search-box">
+    <div class="search-input">
+      <input ref="inputField" v-model="searchValue" v-show="isSearch" type="text"
+        @blur="searchValue == '' ? isSearch = false : ''">
+      <div v-show="!isSearch" @click="() => { isSearch = true, focusInput() }"
+        style="display: flex;justify-content: center; align-items: center;color: #88866F;"><img
+          style="width: 20px;margin-right: 10px;" src="@/assets/images/search_icon.png" alt="">请输入关键词</div>
+    </div>
+  </div>
+</template>
+
+<style lang='less' scoped>
+.search-box {
+  width: 100%;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  height: 7vh;
+
+  .search-input {
+    width: 80%;
+    height: 60%;
+    border-radius: 50px;
+    background: #F1E9D4;
+    margin-top: 1vh;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+
+    input {
+      border: none;
+      background: transparent;
+      width: 90%;
+      height: 80%;
+    }
+  }
+}
+</style>

+ 91 - 99
src/views/EnterNingguo/artwork.vue

@@ -2,131 +2,86 @@
 <script setup lang='ts'>
 import { ArtworkApi } from '@/api/api/artwork'
 import { showToast } from 'vant'
-
+import SearchInput from '@/components/SearchInput/index.vue'
 
 export type artworkType = {
-  id: number
-  title: string
-  thebm: string
-  url: string
-  releaseTime: string
+  createTime: string,
+  creatorId: null,
+  creatorName: string,
+  id: number,
+  link: string,
+  name: string,
+  // 发布日期
+  publishDate: string,
+  thumb: string,
+  updateTime: string
 }
 
-const searchValue = ref('')
+const searchParames = ref({
+  pageNum: 0,
+  pageSize: 0,
+  searchKey: ''
+} as {
+  pageNum: number,
+  pageSize: number,
+  searchKey: string
+})
 
 const searchList = ref([] as artworkType[])
 
 
-const onSearch = () => {
-
-}
-
-const onCancel = () => {
-
-}
-
 
 const getList = async () => {
-  const res: any = await ArtworkApi.getSearchByKeyword({ keyword: searchValue })
+  const res: any = await ArtworkApi.getSearchByKeyword(searchParames.value)
   if (res.code == 0) {
-    searchList.value = res.data
+    searchList.value = res.data.records
   } else {
-    showToast('活动信息获取失败')
+    showToast(res.msg)
   }
 }
 
+const onSearch = (eventData: any) => {
+  searchParames.value.searchKey = eventData
+  getList()
+}
+
+const isShowIframe = ref(false)
+const iframeLink = ref('')
+
+
 onBeforeMount(() => {
   // getList()
-  searchList.value = [
-    {
-      id: 0,
-      title: '好物好物好物好物好物好物好物好物好物好物好物好物好物好物好物好物好物好物好物好物好物',
-      thebm: 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.alicdn.com%2Fbao%2Fuploaded%2Fi3%2F2209785631188%2FO1CN016n4XME1Ke9GzZUhjw_%21%210-item_pic.jpg&refer=http%3A%2F%2Fimg.alicdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1715313398&t=69a2df03775aed2b358ad38a1427108a',
-      url: '',
-      releaseTime: ''
-    },
-    {
-      id: 1,
-      title: '好物好物好物好物好物好物好物好物好物好物好物好物好物好物好物好物好物好物好物好物好物',
-      thebm: 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201901%2F25%2F20190125175611_ANBHn.jpeg&refer=http%3A%2F%2Fb-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1715313455&t=c5c12a6bcb52af950f13f93b94dee082',
-      url: '',
-      releaseTime: ''
-    },
-    {
-      id: 2,
-      title: '好物好物好物好物好物好物好物好物好物好物',
-      thebm: 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201901%2F25%2F20190125175611_ANBHn.jpeg&refer=http%3A%2F%2Fb-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1715313455&t=c5c12a6bcb52af950f13f93b94dee082',
-      url: '',
-      releaseTime: ''
-    },
-    {
-      id: 0,
-      title: '好物好物好物好物好物好物好物好物好物好物好物好物好物好物好物好物好物好物好物好物好物',
-      thebm: 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.alicdn.com%2Fbao%2Fuploaded%2Fi3%2F2209785631188%2FO1CN016n4XME1Ke9GzZUhjw_%21%210-item_pic.jpg&refer=http%3A%2F%2Fimg.alicdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1715313398&t=69a2df03775aed2b358ad38a1427108a',
-      url: '',
-      releaseTime: ''
-    },
-    {
-      id: 1,
-      title: '好物好物好物好物好物好物好物好物好物好物好物好物好物好物好物好物好物好物好物好物好物',
-      thebm: 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201901%2F25%2F20190125175611_ANBHn.jpeg&refer=http%3A%2F%2Fb-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1715313455&t=c5c12a6bcb52af950f13f93b94dee082',
-      url: '',
-      releaseTime: ''
-    },
-    {
-      id: 2,
-      title: '好物好物好物好物好物好物好物好物好物好物',
-      thebm: 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201901%2F25%2F20190125175611_ANBHn.jpeg&refer=http%3A%2F%2Fb-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1715313455&t=c5c12a6bcb52af950f13f93b94dee082',
-      url: '',
-      releaseTime: ''
-    },
-    {
-      id: 0,
-      title: '好物好物好物好物好物好物好物好物好物好物好物好物好物好物好物好物好物好物好物好物好物',
-      thebm: 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.alicdn.com%2Fbao%2Fuploaded%2Fi3%2F2209785631188%2FO1CN016n4XME1Ke9GzZUhjw_%21%210-item_pic.jpg&refer=http%3A%2F%2Fimg.alicdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1715313398&t=69a2df03775aed2b358ad38a1427108a',
-      url: '',
-      releaseTime: ''
-    },
-    {
-      id: 1,
-      title: '好物好物好物好物好物好物好物好物好物好物好物好物好物好物好物好物好物好物好物好物好物',
-      thebm: 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201901%2F25%2F20190125175611_ANBHn.jpeg&refer=http%3A%2F%2Fb-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1715313455&t=c5c12a6bcb52af950f13f93b94dee082',
-      url: '',
-      releaseTime: ''
-    },
-    {
-      id: 2,
-      title: '好物好物好物好物好物好物好物好物好物好物',
-      thebm: 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201901%2F25%2F20190125175611_ANBHn.jpeg&refer=http%3A%2F%2Fb-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1715313455&t=c5c12a6bcb52af950f13f93b94dee082',
-      url: '',
-      releaseTime: ''
-    },
-  ]
 })
 
 </script>
 
 <template>
   <div class='artwork-box'>
-    <div class="search-box">
-      <van-search v-model="searchValue" @search="onSearch" @cancel="onCancel" placeholder="请输入搜索关键词" />
-    </div>
-    <div class="search-list">
-      <div class="list-item" v-for="(item, index) in searchList" :key="index">
-        <img :src="item.thebm" alt="">
-        <div class="title">{{ item.title }}</div>
+    <SearchInput @onSearch="onSearch" />
+    <div class="search-list" v-if="searchList.length > 0">
+      <div class="list-item" v-for="(item, index) in searchList" :key="index"
+        @click="() => { isShowIframe = true, iframeLink = item.link }">
+        <img :src="item.thumb" alt="">
+        <div class="name">{{ item.name }}</div>
       </div>
     </div>
+    <div class="no-data" v-else>
+      <img src="@/assets/images/no-data.png" alt="">
+      <div class="tips">暂时没有数据 ,请试一下其他关键字</div>
+    </div>
   </div>
+  <div class="iframe-box" v-show="isShowIframe">
+    <img src="@/assets/images/sceneBack.png" alt="" @click="isShowIframe = false">
+    <iframe :src="iframeLink" frameborder="0"></iframe>
+  </div>
+
 </template>
 
 <style lang='less' scoped>
 .artwork-box {
   width: 100%;
-
-  .search-box {
-    width: 100%;
-  }
+  min-height: 100%;
+  background: #F7F3E8;
 
   .search-list {
     width: 100%;
@@ -141,19 +96,22 @@ onBeforeMount(() => {
     .list-item {
       width: 100%;
       height: auto;
-      background: rgb(163, 161, 161);
-      padding: 10px;
+      background: #F7F3E8;
+      // padding: 10px;
       box-sizing: border-box;
+      box-shadow: 0px 0px 20px 0px rgba(222, 216, 199, 0.6);
+      border-radius: 10px 10px 10px 10px;
+      padding-bottom: 10px;
 
       img {
         width: 100%;
-        height: 25vh;
+        height: 21vh;
         object-fit: cover;
+        border-radius: 10px 10px 0 0;
       }
 
-      .title {
+      .name {
         font-size: 1em;
-        font-weight: bold;
         display: -webkit-box;
         /* 必须添加,以启用WebKit的弹性盒模型布局 */
         -webkit-line-clamp: 2;
@@ -167,8 +125,42 @@ onBeforeMount(() => {
         /* 末尾显示省略号 */
         word-break: break-all;
         /* 可选,根据需要断开长单词以适应行宽 */
+        padding: 5px 10px 0 10px;
+        font-family: 'SourceHanSansCN-Regular';
+        color: #333333;
+        text-align: justified;
       }
     }
   }
+
+  .no-data {
+    width: 100%;
+    height: calc(100% -7vh);
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+    align-items: center;
+    margin-top: 10%;
+
+
+    img {
+      width: 40%;
+    }
+
+    .tips {
+      color: #88866F;
+      margin-top: 10px;
+      font-family: 'SourceHanSansCN-Regular';
+    }
+
+  }
+}
+
+.iframe {
+  width: 100%;
+  height: 100%;
+  position: absolute;
+  top: 0;
+  left: 0;
 }
 </style>

+ 61 - 42
src/views/EnterNingguo/dynamic-detail.vue

@@ -51,75 +51,94 @@ onBeforeMount(async () => {
 <template>
   <div class='detail-box'>
     <img class="themb-box" :src="dynamicDetail.thebm" alt="">
-    <div class="title-box">{{ dynamicDetail.title }}</div>
-    <div class="time-box">发布时间:{{ dynamicDetail.releaseTime }}</div>
-    <div class="abstract-box">{{ dynamicDetail.abstract }}</div>
-    <div class="mainbody-box" v-html="dynamicDetail.mainBody"></div>
-    <div class="video-box">
-      <video :src="item" controls v-for="(item, index) in dynamicDetail.videos" :key="index"></video>
+    <div class="content-box">
+      <div class="title-box">{{ dynamicDetail.title }}</div>
+      <div class="time-box">发布时间:{{ dynamicDetail.releaseTime }}</div>
+      <div class="abstract-box">{{ dynamicDetail.abstract }}</div>
+      <div class="mainbody-box" v-html="dynamicDetail.mainBody"></div>
+      <div class="video-box">
+        <video :src="item" controls v-for="(item, index) in dynamicDetail.videos" :key="index"></video>
+      </div>
     </div>
-    <img class="back-icon" @click="() => {router.back()}" src="@/assets/images/back.png" alt="">
+    <img class="back-icon" @click="() => { router.back() }" src="@/assets/images/back.png" alt="">
   </div>
 </template>
 
 <style lang='less' scoped>
 .detail-box {
   width: 100%;
+  min-height: 100%;
 
   .themb-box {
     width: 100%;
-    height: auto;
-    margin-bottom: 10px;
-
+    height: 30vh;
+    object-fit: cover;
   }
 
-  .title-box {
-    font-size: 1.2em;
-    font-weight: bold;
-    line-height: 1.5em;
-    color: black;
-    margin-bottom: 10px;
-    padding: 0 10px;
-
+  .content-box {
+    width: 100%;
+    height: calc(70vh + 25px);
+    background:#F7F3E8 ;
+    border-radius: 20px 20px 0 0;
+    margin-top: -30px;
+    position: relative;
+    z-index: 2;
+    padding: 8% 15px;
+    box-sizing: border-box;
+    overflow: auto;
+    .title-box {
+      font-size: 1.4em;
+      font-weight: bold;
+      line-height: 1.5em;
+      color: #333333;
+      margin-bottom: 10px;
+      padding: 0 10px;
+      font-family: 'SourceHanSansCN-Medium';
+      margin-bottom: 5px;
 
-  }
+    }
 
-  .time-box {
-    color: rgba(128, 128, 128, 0.664);
-    font-size: 0.9em;
-    margin-bottom: 10px;
-    padding: 0 10px;
+    .time-box {
+      color: #9D4F0B;
+      font-size: 0.9em;
+      margin-bottom: 15px;
+      padding: 0 10px;
+      font-family: 'SourceHanSansCN-Regular';
 
+    }
 
-  }
+    .abstract-box {
+      color: #88866F;
+      font-size: 1em;
+      margin-bottom: 10px;
+      padding: 0 10px;
+      font-family: 'SourceHanSansCN-Medium';
 
-  .abstract-box {
-    color: rgba(128, 128, 128, 0.664);
-    font-size: 1em;
-    margin-bottom: 10px;
-    padding: 0 10px;
 
+    }
 
-  }
+    .mainbody-box {
+      white-space: pre;
+      margin-bottom: 10px;
+      padding: 0 10px;
 
-  .mainbody-box {
-    white-space: pre;
-    margin-bottom: 10px;
-    padding: 0 10px;
 
+    }
 
-  }
+    .video-box {
+      width: 100%;
 
-  .video-box {
-    width: 100%;
+      video {
+        width: 100%;
+        margin-bottom: 10px;
+      }
 
-    video {
-      width: 100%;
-      margin-bottom: 10px;
     }
 
   }
-  .back-icon{
+
+
+  .back-icon {
     width: 40px;
     position: fixed;
     right: 10px;

+ 158 - 23
src/views/EnterNingguo/dynamic.vue

@@ -10,12 +10,22 @@ const router = useRouter()
 
 const data = ref([] as any)
 
+const searchParames = ref({
+  pageNum: 0,
+  pageSize: 0,
+  searchKey: ''
+} as {
+  pageNum: number,
+  pageSize: number,
+  searchKey: string
+})
+
 const goDetai = (id: number) => {
   router.push({ name: 'dynamicDetail', params: { id } });
 }
 
 const getList = async () => {
-  const res: any = await DynamicApi.getDynamicList()
+  const res: any = await DynamicApi.getDynamicList(searchParames.value)
   if (res.code == 0) {
     data.value = res.data
   } else {
@@ -138,6 +148,67 @@ onBeforeMount(() => {
           releaseTime: '2023-12-27'
         },
       ]
+    },
+    {
+      type: '展览开放',
+      activitys: [
+        {
+          id: 7,
+          title: '宁国博物馆开放日',
+          thebm: 'https://n.sinaimg.cn/sinakd20112/0/w2048h1152/20220428/03e8-399a8decd0e38baf901f375ef9a4c050.jpg',
+          abstract: '这是摘要这是摘要',
+          mainBody: '这是正文这是正文这是正文这是正文这是正文这是正文这是正文这是正文这是正文这是正文',
+          videos: [
+            'https://wxfalangchang.4dage.com/national/1687243969660/thumb/20230710_094753323140.mp4'
+          ],
+          releaseTime: '2023-12-27'
+        },
+      ]
+    }, {
+      type: '展览开放',
+      activitys: [
+        {
+          id: 7,
+          title: '宁国博物馆开放日',
+          thebm: 'https://n.sinaimg.cn/sinakd20112/0/w2048h1152/20220428/03e8-399a8decd0e38baf901f375ef9a4c050.jpg',
+          abstract: '这是摘要这是摘要',
+          mainBody: '这是正文这是正文这是正文这是正文这是正文这是正文这是正文这是正文这是正文这是正文',
+          videos: [
+            'https://wxfalangchang.4dage.com/national/1687243969660/thumb/20230710_094753323140.mp4'
+          ],
+          releaseTime: '2023-12-27'
+        },
+      ]
+    }, {
+      type: '展览开放',
+      activitys: [
+        {
+          id: 7,
+          title: '宁国博物馆开放日',
+          thebm: 'https://n.sinaimg.cn/sinakd20112/0/w2048h1152/20220428/03e8-399a8decd0e38baf901f375ef9a4c050.jpg',
+          abstract: '这是摘要这是摘要',
+          mainBody: '这是正文这是正文这是正文这是正文这是正文这是正文这是正文这是正文这是正文这是正文',
+          videos: [
+            'https://wxfalangchang.4dage.com/national/1687243969660/thumb/20230710_094753323140.mp4'
+          ],
+          releaseTime: '2023-12-27'
+        },
+      ]
+    }, {
+      type: '展览开放',
+      activitys: [
+        {
+          id: 7,
+          title: '宁国博物馆开放日',
+          thebm: 'https://n.sinaimg.cn/sinakd20112/0/w2048h1152/20220428/03e8-399a8decd0e38baf901f375ef9a4c050.jpg',
+          abstract: '这是摘要这是摘要',
+          mainBody: '这是正文这是正文这是正文这是正文这是正文这是正文这是正文这是正文这是正文这是正文',
+          videos: [
+            'https://wxfalangchang.4dage.com/national/1687243969660/thumb/20230710_094753323140.mp4'
+          ],
+          releaseTime: '2023-12-27'
+        },
+      ]
     }
   ]
 })
@@ -145,22 +216,27 @@ onBeforeMount(() => {
 
 <template>
   <div class='dynamic'>
-    <van-tabs v-model:active="active" id="tabs">
+    <!-- <van-tabs v-model:active="active" id="tabs">
       <van-tab v-for="(item, index) in data" :key="index" :title="item.type">
-        <!-- <div>{{ active }}</div> -->
-        <div class="tab-content">
-          <div class="activity-card" v-for="(item, index) in data[active].activitys" :key="index"
-            @click="goDetai(item.id)">
-            <img v-show="item.thebm != ''" class="thebm" :src="item.thebm" alt="">
-            <div class="title">{{ item.title }}</div>
-            <div v-show="item.abstract != ''" class="abstract">{{ item.abstract }}</div>
-            <div class="time">
-              {{ item.releaseTime }}
-            </div>
-          </div>
-        </div>
+       
       </van-tab>
-    </van-tabs>
+    </van-tabs> -->
+
+    <div class="tabs">
+      <div class="tab-item" :class="{ active: index === active }" v-for="(item, index) in data" :key="item"
+        @click="active = index">{{ item.type }}</div>
+    </div>
+
+    <div class="tab-content">
+      <div class="activity-card" v-for="(item, index) in data[active].activitys" :key="index" @click="goDetai(item.id)">
+        <img v-show="item.thebm != ''" class="thebm" :src="item.thebm" alt="">
+        <div class="title">{{ item.title }}</div>
+        <div v-show="item.abstract != ''" class="abstract">{{ item.abstract }}</div>
+        <div class="time">
+          发布时间:{{ item.releaseTime }}
+        </div>
+      </div>
+    </div>
   </div>
 </template>
 
@@ -169,39 +245,98 @@ onBeforeMount(() => {
   box-sizing: border-box;
 }
 
+
+
 .dynamic {
   width: 100%;
+  background: #F7F3E8;
+  min-height: 100%;
+
+
+  .tabs {
+    // height: 40px;
+    white-space: nowrap;
+    overflow-x: auto;
+    padding: 15px 10px 10px 0px;
+    font-family: 'SourceHanSansCN-Regular';
+
+    &::-webkit-scrollbar {
+      display: none;
+      /* 或 width: 0; */
+    }
+
+    .tab-item {
+      margin-left: 10px;
+      display: inline-block;
+      width: 85px;
+      height: 30px;
+      float: none;
+      font-size: 0.9rem;
+      line-height: 30px;
+      text-align: center;
+      background-color: #F1E9D4;
+      border-radius: 5px;
+      // box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.3);
+      color: rgba(0, 0, 0, 0.8);
+      color: #88866F;
+    }
+
+    .active {
+      background: #9D4F0B;
+      color: #F7F3E8;
+    }
+  }
 
   // padding: 0 10px;\
   .tab-content {
     width: 100%;
-    padding: 10px;
+    padding: 20px;
+    max-height: calc(100vh - 8vh);
+    overflow: auto;
+
+    &::-webkit-scrollbar {
+      display: none;
+      /* 或 width: 0; */
+    }
 
     .activity-card {
       width: 100%;
-      background: rgba(177, 177, 177, 0.226);
+      // background: rgba(177, 177, 177, 0.226);
       border-radius: 15px;
-      padding: 20px;
+      // padding: 20px;
       margin-bottom: 20px;
 
       .thebm {
         width: 100%;
+        border-radius: 5px;
+        margin-bottom: 20px;
       }
 
       .title {
-        font-size: 1.2em;
+        font-size: 1.3em;
         font-weight: bold;
-        line-height: 1.3em;
+        color: #333333;
+        font-family: 'SourceHanSansCN-Medium';
+        line-height: 1.5em;
+        margin-bottom: 10px;
       }
 
       .abstract {
-        font-size: 0.9em;
-        color: gray;
+        font-size: 1.1em;
+        color: #88866F;
+        line-height: 1.4em;
+        font-family: 'SourceHanSansCN-Regular';
+        margin-bottom: 5px;
+
       }
 
       .time {
+        font-size: 0.9em;
+        line-height: 1.4em;
         width: 100%;
-        text-align: right;
+        color: #9D4F0B;
+        font-family: 'SourceHanSansCN-Regular';
+
       }
 
 

File diff suppressed because it is too large
+ 66 - 12
src/views/EnterNingguo/summarize.vue


File diff suppressed because it is too large
+ 87 - 65
src/views/ExhibitionService/active-detail.vue


+ 142 - 25
src/views/ExhibitionService/active-info.vue

@@ -1,61 +1,94 @@
 <script setup lang='ts'>
+import { VolunteerApi } from '@/api/api/volunteerHome';
 import { showToast } from 'vant';
 
 const route = useRoute()
+const router = useRouter()
+
 
 export type infoDetailType = {
   name: string,
   phone: string,
-  idCard: string,
-  explain: string
+  identity: string,
+  description: string,
+  type: string
 }
 
 const infoDetail = ref({
   name: '',
   phone: '',
-  idCard: '',
-  explain: ''
+  identity: '',
+  description: '',
+  type: 'activity',
+  title: route.params.title
 } as infoDetailType)
 
-const submit = () => {
-  if(infoDetail.value.name.length == 0){
+const submit = async () => {
+  if (infoDetail.value.name.length == 0) {
     showToast('预约姓名不能为空!')
-    return 
+    return
   }
 
-  if(infoDetail.value.phone.length == 0){
+  if (infoDetail.value.phone.length == 0) {
     showToast('预约联系电话不能为空!')
-    return 
+    return
   }
-  
-  if(!/^((1[3-9]\d{9})|(09\d{8}))$/.test(infoDetail.value.phone)){
+
+  if (!/^((1[3-9]\d{9})|(09\d{8}))$/.test(infoDetail.value.phone)) {
     showToast('请输入正确的联系电话!')
     return
   }
 
 
-  if(infoDetail.value.idCard.length == 0){
+  if (infoDetail.value.identity.length == 0) {
     showToast('预约身份证号不能为空!')
-    return 
+    return
   }
 
-  if(!/^(^\d{6}(18|19|20)?\d{2}(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])\d{3}(\d|X|x))$/.test(infoDetail.value.idCard)){
+  if (!/^(^\d{6}(18|19|20)?\d{2}(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])\d{3}(\d|X|x))$/.test(infoDetail.value.identity)) {
     showToast('请输入正确的身份证号!')
     return
   }
 
+  const res: any = await VolunteerApi.saveApplyAPI(infoDetail.value)
+  if (res.code == 0) {
+    showToast('预约成功')
+    router.back()
+  } else {
+    showToast(res.msg)
+  }
+
+
 }
 
 </script>
 
 <template>
   <div class='info-box'>
+    <div class="page-title">
+      <img src="@/assets/images/cicle.png" alt="">
+      <div class="title-content">活动预约</div>
+    </div>
     <div class="title">{{ route.params.title }}</div>
     <div class="form">
-      <van-field v-model="infoDetail.name" required label="姓名" placeholder="请输入内容" />
-      <van-field v-model="infoDetail.phone" required label="联系电话" placeholder="请输入内容" />
-      <van-field v-model="infoDetail.idCard" required label="身份证号" placeholder="请输入内容" />
-      <van-field v-model="infoDetail.explain" label="预约说明" placeholder="请输入您想参加的活动或其他需求" />
+
+      <div class="input-item">
+        <span style="color: red;">*</span>
+        <div class="label">姓名:</div><input type="text" v-model="infoDetail.name" placeholder="请输入内容">
+      </div>
+      <div class="input-item">
+        <span style="color: red;">*</span>
+        <div class="label">联系电话:</div><input type="text" v-model="infoDetail.phone" placeholder="请输入内容">
+      </div>
+      <div class="input-item">
+        <span style="color: red;">*</span>
+        <div class="label">身份证号:</div><input type="text" v-model="infoDetail.identity" placeholder="请输入内容">
+      </div>
+      <div class="input-item">
+        <!-- <span style="color: red;">*</span> -->
+        <div class="label">预约说明:</div><textarea cols="30" rows="10" v-model="infoDetail.description"
+          placeholder="请输入您想参加的活动或其他需求"></textarea>
+      </div>
     </div>
     <div class="commit-box">
       <div class="tips"> 提交后,请等待工作人员与您取得联系</div>
@@ -71,12 +104,94 @@ const submit = () => {
 
 .info-box {
   width: 100%;
-  height: 100%;
+  height: 100vh;
   padding: 20px;
+  background: #F7F3E8;
+
+  .page-title {
+    font-size: 1.4em;
+    color: #333333;
+    font-weight: bold;
+    position: relative;
+    // line-height: 1.6em;
+    display: flex;
+    align-items: flex-end;
+    margin-bottom: 10px;
+
+    img {
+      position: absolute;
+      left: 0;
+      top: 0;
+      height: 1.6em;
+    }
 
+    .title-content {
+      // position: absolute;
+      position: relative;
+      left: 0;
+      top: 0;
+      height: 1.4em;
+      z-index: 2;
+      line-height: 1.6em;
+      color: #333333;
+      margin-top: 1%;
+      font-family: SourceHanSansCN-Bold;
 
+    }
 
-  .form {}
+  }
+
+  .title {
+    color: #9D4F0B;
+    font-family: 'SourceHanSansCN-Medium';
+    margin-top: 8%;
+    margin-bottom: 5%;
+    font-size: 1.1em;
+  }
+
+  .form {
+    width: 100%;
+
+    .input-item {
+      width: 100%;
+      display: flex;
+      margin: 10px auto;
+      height: 50px;
+
+      span {
+        margin-right: 10px;
+      }
+
+      .label {
+        width: 30%;
+        text-align: left;
+        color: #333333;
+      }
+
+      input {
+        width: 80%;
+        height: 70%;
+        border: 1px solid #9D4F0B;
+        border-radius: 5px;
+        padding: 0 10px;
+        background: #FFFDF6;
+        color: #88866F;
+        font-size: 0.9em;
+      }
+
+      textarea {
+        width: 80%;
+        height: 30vh;
+        border: 1px solid #9D4F0B;
+        border-radius: 5px;
+        padding: 10px;
+        background: #FFFDF6;
+        color: #88866F;
+        font-size: 0.9em;
+      }
+    }
+
+  }
 
   .commit-box {
     position: fixed;
@@ -84,14 +199,16 @@ const submit = () => {
     width: calc(100% - 40px);
 
     .tips {
-      color: rgba(128, 128, 128, 0.767);
+      color: #88866F;
       width: 100%;
       text-align: center;
     }
-    .commit-btn{
+
+    .commit-btn {
       width: 100%;
-      height: 40px;
-      background: gray;
+      height: 60px;
+      background: url(@/assets/images/onlineBg.png);
+      background-size: 100% 100%;
       border-radius: 50px;
       color: white;
       font-weight: bold;
@@ -99,7 +216,7 @@ const submit = () => {
       display: flex;
       justify-content: center;
       align-items: center;
-      margin: 10px 0;
+      margin: 30px 0 40px 0;
     }
   }
 }

File diff suppressed because it is too large
+ 162 - 98
src/views/ExhibitionService/activeBooking.vue


+ 6 - 0
src/views/ExhibitionService/bookedList.vue

@@ -1,6 +1,10 @@
 <script setup lang='ts'>
+import BookingTime from './components/BookingTime.vue'
 
 const bookedList = ref([] as any)
+
+// 立即预约-时段选择
+const showBookingTime = ref(false)
 </script>
 
 <template>
@@ -12,6 +16,8 @@ const bookedList = ref([] as any)
         <div>{{ item. }}</div>
       </div> -->
     </div>
+    <div class="booking-btn" @click="showBookingTime = true">发起预约</div>
+    <BookingTime v-show="showBookingTime" />
   </div>
 </template>
 

+ 91 - 0
src/views/ExhibitionService/components/BookingTime.vue

@@ -0,0 +1,91 @@
+<script setup lang='ts'>
+import { sceneBookingApi } from '@/api/api/sceneBooking';
+
+const dateArray = ref([] as any)
+
+
+const getFutureDates = (numDays: number) => {
+  const datesArray = [];
+  const today = new Date();
+  const dateFormat = 'yyyy-MM-dd 星期X'; // 新增星期格式
+
+  for (let i = 0; i <= numDays; i++) {
+    const futureDate = new Date(today.getTime());
+    futureDate.setDate(today.getDate() + i);
+    const formattedDate = formatDate(futureDate, dateFormat);
+    datesArray.push({
+      date: formattedDate
+    });
+  }
+
+  return datesArray;
+}
+
+const formatDate = (date: any, format: any) => {
+  const year = date.getFullYear();
+  const month = String(date.getMonth() + 1).padStart(2, '0');
+  const day = String(date.getDate()).padStart(2, '0');
+  const weekDay = getWeekDay(date);
+
+  return format.replace('yyyy', year)
+    .replace('MM', month)
+    .replace('dd', day)
+    .replace('X', weekDay);
+}
+
+const getWeekDay = (date: any) => {
+  const daysOfWeek = ['日', '一', '二', '三', '四', '五', '六'];
+  return daysOfWeek[date.getDay()];
+}
+
+// 获取禁止预约日期,并加上字段
+const getDisableDate = async () => {
+  const res = await sceneBookingApi.getDisableDateAPi()
+  if (res.data.code === 0) {
+    // 遍历禁止日期
+    res.data.forEach((item: any) => {
+      dateArray.value.forEach((dateItem: any) => {
+        if (item === dateItem.date) {
+          dateItem.disable = true
+        }
+      })
+    })
+  }
+}
+
+// const bookingTimeList = ref([] as any)
+
+// 获得可预约时间段
+// const getBookingTime = async () => {
+//   const res = await sceneBookingApi.getBookingTimeAPI()
+
+// }
+
+onBeforeMount(() => {
+  dateArray.value = getFutureDates(13)
+  getDisableDate()
+  // console.log(getFutureDates(13))
+})
+</script>
+
+<template>
+  <div class='time-box'>
+
+  </div>
+</template>
+
+<style lang='less' scoped>
+.time-box {
+  width: 100%;
+  height: 100%;
+  position: absolute;
+  top: 0px;
+  left: 0px;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  background: gray;
+  margin: 0;
+  box-sizing: border-box;
+}
+</style>

File diff suppressed because it is too large
+ 66 - 46
src/views/SmartTour/exhibition-detail.vue


File diff suppressed because it is too large
+ 135 - 108
src/views/SmartTour/exhibition.vue


+ 71 - 35
src/views/SmartTour/treasure-detail.vue

@@ -10,8 +10,6 @@ const router = useRouter()
 // const route = useRoute()
 
 
-
-
 export type TreasureDetailType = {
   id: number,
   title: string,
@@ -91,7 +89,7 @@ onBeforeMount(async () => {
     era: '朝代',
     character: '质地',
     info: '<p>八骏马图周器垒</p><p>      创造者、设计者:戴嘉林   高:38.8cm 口:12.1cm 足:14cm</p><p>      2017年11月8日,国家主席习近平和夫人彭丽媛陪同来华进行国事访问的美国总统特朗普和夫人梅拉尼娅一同参观故宫。宾主来到畅音阁,沿途欣赏了景泰蓝工艺精品和制作技艺展示,并尝试为景泰蓝《八骏马周器垒》,《国色天香》瓶点蓝,领略中华文化。</p><p></p>',
-    size: '尺寸:志盖边长 40.5 厘米、厚 8.5 厘米、志石边长 41 厘米、厚 9.5 厘米',
+    size: '志盖边长 40.5 厘米、厚 8.5 厘米、志石边长 41 厘米、厚 9.5 厘米',
     themb: 'https://n.sinaimg.cn/sinakd20112/0/w2048h1152/20220428/03e8-399a8decd0e38baf901f375ef9a4c050.jpg',
     files: {
       images: ['https://super.4dage.com/data/TEST/edit/20230407_114029890.jpg', 'https://super.4dage.com/data/TEST/edit/20230524_155459428.png'],
@@ -143,15 +141,21 @@ onBeforeMount(async () => {
     </div>
     <div class="info-box">
       <div class="title">{{ dynamicDetail.title }}</div>
-      <div class="era">{{ dynamicDetail.era + '·' + dynamicDetail.character }}</div>
-      <div class="size"> {{ dynamicDetail.size }}</div>
+      <!-- <div class="era">{{ dynamicDetail.era + '·' + dynamicDetail.character }}</div> -->
+      <div class="era">
+        <div style="margin-right: 20px;">朝代:{{ dynamicDetail.era }}</div>
+        <div>质地:{{ dynamicDetail.character }}</div>
+
+      </div>
+
+      <div class="size">尺寸: {{ dynamicDetail.size }}</div>
       <div class="info" v-html="dynamicDetail.info"></div>
     </div>
 
     <audio id="audioBg" :src="audioBgUrl" style="display: none;"></audio>
     <img v-if="audioBgUrl != null" class="playing-icon" :src="audioPlaying ? pauseIcon : playIcon" alt=""
       @click="audioChange()">
-    <img class="back-icon" @click="() => { router.back() }" src="@/assets/images/back.png" alt="">
+    <!-- <img class="back-icon" @click="() => { router.back() }" src="@/assets/images/back.png" alt=""> -->
   </div>
 </template>
 
@@ -161,20 +165,21 @@ onBeforeMount(async () => {
 
   .media-box {
     width: 100%;
-    height: 30vh;
+    height: 35vh;
     position: relative;
 
     .left-icon {
-      width: 30px;
-      height: 30px;
+      width: 25px;
+      height: auto;
       position: absolute;
-      left: 10px;
+      left: 0;
       top: 50%;
       transform: translateY(-50%);
+      object-fit: fill;
     }
 
     .right-icon {
-      right: 10px;
+      right: 0px;
       left: auto;
     }
 
@@ -199,7 +204,7 @@ onBeforeMount(async () => {
       position: absolute;
       left: 50%;
       transform: translateX(-50%);
-      bottom: 20px;
+      bottom: 35px;
       display: flex;
       justify-content: space-between;
       align-items: center;
@@ -210,9 +215,8 @@ onBeforeMount(async () => {
         box-sizing: border-box;
         line-height: 25px;
         border-radius: 15px;
-        background: white;
-        color: gray;
-        font-weight: bold;
+        background: #9F8E8E;
+        color: #5B4848;
         font-size: 0.8em;
 
         span {
@@ -223,39 +227,71 @@ onBeforeMount(async () => {
       }
 
       .active {
-        background: gray;
-        color: white;
+        background: #5B4848;
+        color: #F7F3E8;
       }
     }
 
-    .info-box{
-      .title{
+  }
 
-      }
-      .era{
+  .info-box {
+    background: #F7F3E8;
+    width: 100%;
+    height: calc(65vh + 20px);
+    margin-top: -20px;
+    padding: 20px;
+    box-sizing: border-box;
+    position: relative;
+    z-index: 2;
+    border-radius: 20px 20px 0 0;
+    overflow: auto;
+
+    .title {
+      color: #333333;
+      font-size: 1.2em;
+      font-weight: bold;
+      line-height: 1.5em;
+      font-family: 'SourceHanSansCN-Medium';
+      margin-bottom: 10px;
+    }
 
-      }
-      .size{
+    .era {
+      line-height: 1.5em;
+      color: #9D4F0B;
+      font-size: 1em;
+      font-family: 'SourceHanSansCN-Regular';
+      display: flex;
+      margin-bottom: 5px;
+    }
 
-      }
-      .info{
-        white-space: pre-wrap;
-      }
+    .size {
+      line-height: 1.5em;
+      color: #9D4F0B;
+      font-size: 1em;
+      font-family: 'SourceHanSansCN-Regular';
+      margin-bottom: 10px;
     }
+
+    .info{
+      color: #88866F;
+    }
+
+
   }
 
   .playing-icon {
     width: 40px;
     position: fixed;
-    right: 10px;
-    bottom: 18vh;
+    right: 15px;
+    bottom: 3vh;
+    z-index: 3;
   }
 
-  .back-icon {
-    width: 40px;
-    position: fixed;
-    right: 10px;
-    bottom: 10vh;
-  }
+  // .back-icon {
+  //   width: 40px;
+  //   position: fixed;
+  //   right: 10px;
+  //   bottom: 10vh;
+  // }
 }
 </style>

+ 141 - 114
src/views/SmartTour/treasure.vue

@@ -2,23 +2,63 @@
 <script setup lang='ts'>
 import { TreasureApi } from '@/api/api/treasure';
 import { showToast } from 'vant';
+import SearchInput from '@/components/SearchInput/index.vue'
+
+export type DictType = {
+  createTime: string | null,
+  creatorId: number | null,
+  creatorName: string | null,
+  display: string | null,
+  id: number | null,
+  name: string | null,
+  parentId: number | null,
+  rtf: string | null,
+  sort: number | null,
+  type: string | null,
+  typeKey: string | null,
+  updateTime: string | null
+}
 
+export type TreasureType = {
+  age: string,
+  createTime: string,
+  creatorId: number,
+  creatorName: string,
+  description: string,
+  dirCode: string,
+  fileIds: string,
+  fileTypes: string,
+  id: 1,
+  name: string,
+  publishDate: string,
+  size: string,
+  texture: string,
+  thumb: string,
+  type: string,
+  updateTime: string
+}
 
-const searchValue = ref('')
-const router = useRouter()
-
-const data = ref([] as any)
 
+const searchParames = ref({
+  pageNum: 0,
+  pageSize: 0,
+  searchKey: '',
+  type: ''
+} as {
+  pageNum: number,
+  pageSize: number,
+  searchKey: string,
+  type: string | null
+})
 
-const activeIndex = ref(0)
+const router = useRouter()
 
-const onSearch = () => {
+const data = ref([] as TreasureType[])
 
-}
+const typeList = ref([] as DictType[])
 
-const onCancel = () => {
 
-}
+const activeIndex = ref(0)
 
 const goDetai = (id: number) => {
   router.push({ name: 'treasureDetail', params: { id } });
@@ -26,100 +66,52 @@ const goDetai = (id: number) => {
 
 
 const getList = async () => {
-  const res: any = await TreasureApi.getTreasureList()
+  searchParames.value.type = activeIndex.value == 0 ? '' : typeList.value[activeIndex.value].name
+  // 获取指定类型的列表
+  const res: any = await TreasureApi.getTreasureList(searchParames.value)
   if (res.code == 0) {
-    data.value = res.data
+    data.value = res.data.records
   } else {
     showToast('活动信息获取失败')
   }
 }
 
 
-onBeforeMount(() => {
-  data.value = [
-    {
-      type: '全部',
-      lists: [
-        {
-          id: 0,
-          title: '《瓜洲马头新建石堤记》碑拓片',
-          type: '全部',
-          era: '朝代',
-          character: '质地',
-          info: '',
-          size: '',
-          themb: 'https://n.sinaimg.cn/sinakd20112/0/w2048h1152/20220428/03e8-399a8decd0e38baf901f375ef9a4c050.jpg',
-          files: {
-            images: [],
-            moduleUrl: '',
-            audio: '',
-            // 可能是单个可能是多个
-            videos: [],
-            releaseTime: '2023-12-27'
-          }
-        }
-      ]
-    },
-    {
-      type: '类型1',
-      lists: [
-        {
-          id: 1,
-          title: '《瓜洲马头新建石堤记》碑拓片',
-          type: '全部',
-          era: '朝代',
-          character: '质地',
-          info: '',
-          size: '',
-          themb: 'https://n.sinaimg.cn/sinakd20112/0/w2048h1152/20220428/03e8-399a8decd0e38baf901f375ef9a4c050.jpg',
-          files: {
-            images: [],
-            moduleUrl: '',
-            audio: '',
-            // 可能是单个可能是多个
-            videos: [],
-            releaseTime: '2023-12-27'
-          }
-        }, {
-          id: 1,
-          title: '《瓜洲马头新建石堤记》碑拓片',
-          type: '全部',
-          era: '朝代',
-          character: '质地',
-          info: '',
-          size: '',
-          themb: 'https://n.sinaimg.cn/sinakd20112/0/w2048h1152/20220428/03e8-399a8decd0e38baf901f375ef9a4c050.jpg',
-          files: {
-            images: [],
-            moduleUrl: '',
-            audio: '',
-            // 可能是单个可能是多个
-            videos: [],
-            releaseTime: '2023-12-27'
-          }
-        }
-      ]
-    },
-    {
-      type: '类型2',
-      lists: [
-
-      ]
-    },
-    {
-      type: '类型3',
-      lists: [
-
-      ]
-    },
-    {
-      type: '类型4',
-      lists: [
-
-      ]
-    }
-  ]
+const getTypeList = async () => {
+  // 获取珍藏类型
+  const resType: any = await TreasureApi.getTypeList()
+  if (resType.code == 0) {
+    typeList.value = resType.data
+    typeList.value.unshift({
+      createTime: null,
+      creatorId: null,
+      creatorName: '',
+      display: null,
+      id: null,
+      name: '全部',
+      parentId: null,
+      rtf: '',
+      sort: null,
+      type: '',
+      typeKey: '',
+      updateTime: null
+    })
+  } else {
+    showToast(resType.msg)
+  }
+
+  getList()
+}
+
+
+const onSearch = (eventData: any) => {
+  searchParames.value.searchKey = eventData
+  getList()
+}
+
 
+onBeforeMount(() => {
+  getTypeList()
 })
 
 
@@ -129,22 +121,27 @@ onBeforeMount(() => {
 
 <template>
   <div class="treasure-box">
-    <div class="search-box">
-      <van-search v-model="searchValue" @search="onSearch" @cancel="onCancel" placeholder="请输入搜索关键词" />
-    </div>
+    <SearchInput @onSearch="onSearch" />
     <div class="content-box">
-      <van-tabs v-model:active="activeIndex">
-        <van-tab v-for="(item, index) in data" :key="index" :title="item.type">
+      <van-tabs v-model:active="activeIndex" color="#9D4F0B" background="#F7F3E8" title-active-color="#9D4F0B"
+        title-inactive-color="#88866F" @change="getList()">
+        <van-tab v-for="(item, index) in typeList" :key="index" :title="item.name">
           <!-- <div>{{ activeIndex }}</div> -->
-          <div class="tab-content" v-if="data[activeIndex].lists.length > 0">
-            <div class="activity-card" v-for="(item, index) in data[activeIndex].lists" :key="index"
-              @click="goDetai(item.id)">
-              <img v-show="item.themb != ''" class="themb" :src="item.themb" alt="">
-              <div class="detail">{{ item.era + '·' + item.character }}</div>
-              <div class="title">{{ item.title }}</div>
+          <div class="tab-content" v-if="data.length > 0">
+            <div class="activity-card" v-for="(item, index) in data" :key="index" @click="goDetai(item.id)">
+              <img v-show="item.thumb != ''" class="thumb" :src="item.thumb" alt="">
+              <div class="title">{{ item.name }}</div>
+              <div class="detail">
+                <div style="margin-right: 30px;">朝代:{{ item.age }}</div>
+                <div>质地:{{ item.texture }}</div>
+              </div>
+
             </div>
           </div>
-          <div v-else class="no-data">暂无内容</div>
+          <div v-else class="no-data">
+            <img src="@/assets/images/no-data.png" alt="">
+            <div class="tips">暂时没有数据 ,请试一下其他关键字</div>
+          </div>
         </van-tab>
       </van-tabs>
     </div>
@@ -152,18 +149,27 @@ onBeforeMount(() => {
 </template>
 
 <style lang='less' scoped>
+.van-tabs__content {
+  background-color: #F7F3E8;
+}
+
 .treasure-box {
   width: 100%;
+  min-height: 100%;
+  background: #F7F3E8;
 
-  .search-box {
-    width: 100%;
-  }
 
   .content-box {
     width: 100%;
     padding: 0px 10px;
     box-sizing: border-box;
 
+    .van-tabs {
+      .van-tabs__nav {
+        background: #F7F3E8 !important;
+      }
+    }
+
     .tab-content {
       width: 100%;
 
@@ -173,30 +179,51 @@ onBeforeMount(() => {
         box-sizing: border-box;
         margin-bottom: 20px;
 
+
         img {
           width: 100%;
+          border-radius: 10px;
         }
 
         .detail {
-          font-size: 0.8em;
-          color: gray;
+          font-size: 1em;
+          color: #9D4F0B;
           margin-top: 10px;
+          font-family: 'SourceHanSansCN-Regular';
+          display: flex;
+
         }
 
         .title {
-          font-size: 1em;
+          font-size: 1.2em;
           font-weight: bold;
           margin-top: 5px;
+          color: #333333;
+          font-family: 'SourceHanSansCN-Medium';
         }
       }
     }
 
     .no-data {
       width: 100%;
-      height: 80vh;
+      height: calc(100% -7vh);
       display: flex;
+      flex-direction: column;
       justify-content: center;
       align-items: center;
+      margin-top: 10%;
+
+
+      img {
+        width: 40%;
+      }
+
+      .tips {
+        color: #88866F;
+        margin-top: 10px;
+        font-family: 'SourceHanSansCN-Regular';
+      }
+
     }
   }
 }

+ 141 - 25
src/views/VolunteerHome/apply.vue

@@ -1,48 +1,61 @@
+<!-- eslint-disable vue/multi-word-component-names -->
 <script setup lang='ts'>
 import { showToast } from 'vant';
+import { VolunteerApi } from '@/api/api/volunteerHome';
+import router from '@/router';
+
 
 const route = useRoute()
 
 export type infoDetailType = {
   name: string,
   phone: string,
-  idCard: string,
-  explain: string
+  identity: string,
+  description: string,
+  type: string
 }
 
 const infoDetail = ref({
   name: '',
   phone: '',
-  idCard: '',
-  explain: ''
+  identity: '',
+  description: '',
+  type: 'volunteer'
 } as infoDetailType)
 
-const submit = () => {
-  if(infoDetail.value.name.length == 0){
+const submit = async () => {
+  if (infoDetail.value.name.length == 0) {
     showToast('预约姓名不能为空!')
-    return 
+    return
   }
 
-  if(infoDetail.value.phone.length == 0){
+  if (infoDetail.value.phone.length == 0) {
     showToast('预约联系电话不能为空!')
-    return 
+    return
   }
-  
-  if(!/^((1[3-9]\d{9})|(09\d{8}))$/.test(infoDetail.value.phone)){
+
+  if (!/^((1[3-9]\d{9})|(09\d{8}))$/.test(infoDetail.value.phone)) {
     showToast('请输入正确的联系电话!')
     return
   }
 
 
-  if(infoDetail.value.idCard.length == 0){
+  if (infoDetail.value.identity.length == 0) {
     showToast('预约身份证号不能为空!')
-    return 
+    return
   }
 
-  if(!/^(^\d{6}(18|19|20)?\d{2}(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])\d{3}(\d|X|x))$/.test(infoDetail.value.idCard)){
+  if (!/^(^\d{6}(18|19|20)?\d{2}(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])\d{3}(\d|X|x))$/.test(infoDetail.value.identity)) {
     showToast('请输入正确的身份证号!')
     return
   }
+  const res: any = await VolunteerApi.saveApplyAPI(infoDetail.value)
+  if (res.code == 0) {
+    showToast('申请成功')
+    router.back()
+  }else {
+    showToast(res.msg)
+  }
 
 }
 
@@ -50,11 +63,30 @@ const submit = () => {
 
 <template>
   <div class='info-box'>
+    <div class="page-title">
+      <img src="@/assets/images/cicle.png" alt="">
+      <div class="title-content">志愿者申请</div>
+    </div>
+    <div class="title">{{ route.params.title }}</div>
     <div class="form">
-      <van-field v-model="infoDetail.name" required label="姓名" placeholder="请输入内容" />
-      <van-field v-model="infoDetail.phone" required label="联系电话" placeholder="请输入内容" />
-      <van-field v-model="infoDetail.idCard" required label="身份证号" placeholder="请输入内容" />
-      <van-field v-model="infoDetail.explain" label="预约说明" placeholder="请输入您想参加的活动或其他需求" />
+
+      <div class="input-item">
+        <span style="color: red;">*</span>
+        <div class="label">姓名:</div><input type="text" v-model="infoDetail.name" placeholder="请输入内容">
+      </div>
+      <div class="input-item">
+        <span style="color: red;">*</span>
+        <div class="label">联系电话:</div><input type="text" v-model="infoDetail.phone" placeholder="请输入内容">
+      </div>
+      <div class="input-item">
+        <span style="color: red;">*</span>
+        <div class="label">身份证号:</div><input type="text" v-model="infoDetail.identity" placeholder="请输入内容">
+      </div>
+      <div class="input-item">
+        <!-- <span style="color: red;">*</span> -->
+        <div class="label">预约说明:</div><textarea cols="30" rows="10" v-model="infoDetail.description"
+          placeholder="请输入您想参加的活动或其他需求"></textarea>
+      </div>
     </div>
     <div class="commit-box">
       <div class="tips"> 提交后,请等待工作人员与您取得联系</div>
@@ -70,12 +102,94 @@ const submit = () => {
 
 .info-box {
   width: 100%;
-  height: 100%;
+  height: 100vh;
   padding: 20px;
+  background: #F7F3E8;
+
+  .page-title {
+    font-size: 1.4em;
+    color: #333333;
+    font-weight: bold;
+    position: relative;
+    // line-height: 1.6em;
+    display: flex;
+    align-items: flex-end;
+    margin-bottom: 10px;
+
+    img {
+      position: absolute;
+      left: 0;
+      top: 0;
+      height: 1.6em;
+    }
 
+    .title-content {
+      // position: absolute;
+      position: relative;
+      left: 0;
+      top: 0;
+      height: 1.4em;
+      z-index: 2;
+      line-height: 1.6em;
+      color: #333333;
+      margin-top: 1%;
+      font-family: SourceHanSansCN-Bold;
 
+    }
 
-  .form {}
+  }
+
+  .title {
+    color: #9D4F0B;
+    font-family: 'SourceHanSansCN-Medium';
+    margin-top: 8%;
+    margin-bottom: 5%;
+    font-size: 1.1em;
+  }
+
+  .form {
+    width: 100%;
+
+    .input-item {
+      width: 100%;
+      display: flex;
+      margin: 10px auto;
+      height: 50px;
+
+      span {
+        margin-right: 10px;
+      }
+
+      .label {
+        width: 30%;
+        text-align: left;
+        color: #333333;
+      }
+
+      input {
+        width: 80%;
+        height: 70%;
+        border: 1px solid #9D4F0B;
+        border-radius: 5px;
+        padding: 0 10px;
+        background: #FFFDF6;
+        color: #88866F;
+        font-size: 0.9em;
+      }
+
+      textarea {
+        width: 80%;
+        height: 30vh;
+        border: 1px solid #9D4F0B;
+        border-radius: 5px;
+        padding: 10px;
+        background: #FFFDF6;
+        color: #88866F;
+        font-size: 0.9em;
+      }
+    }
+
+  }
 
   .commit-box {
     position: fixed;
@@ -83,14 +197,16 @@ const submit = () => {
     width: calc(100% - 40px);
 
     .tips {
-      color: rgba(128, 128, 128, 0.767);
+      color: #88866F;
       width: 100%;
       text-align: center;
     }
-    .commit-btn{
+
+    .commit-btn {
       width: 100%;
-      height: 40px;
-      background: gray;
+      height: 60px;
+      background: url(@/assets/images/onlineBg.png);
+      background-size: 100% 100%;
       border-radius: 50px;
       color: white;
       font-weight: bold;
@@ -98,7 +214,7 @@ const submit = () => {
       display: flex;
       justify-content: center;
       align-items: center;
-      margin: 10px 0;
+      margin: 30px 0 40px 0;
     }
   }
 }

File diff suppressed because it is too large
+ 81 - 99
src/views/VolunteerHome/detail.vue


File diff suppressed because it is too large
+ 158 - 84
src/views/VolunteerHome/home.vue