xiaoxin 2 лет назад
Родитель
Сommit
d31219f09d

+ 4 - 3
package-lock.json

@@ -14,6 +14,7 @@
         "@element-plus/icons-vue": "^2.3.1",
         "axios": "^1.6.7",
         "countup.js": "^2.8.0",
+        "dayjs": "^1.11.11",
         "echarts": "^5.5.0",
         "element-plus": "^2.6.1",
         "moment": "^2.30.1",
@@ -1019,9 +1020,9 @@
       "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
     },
     "node_modules/dayjs": {
-      "version": "1.11.10",
-      "resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.10.tgz",
-      "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ=="
+      "version": "1.11.11",
+      "resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.11.tgz",
+      "integrity": "sha512-okzr3f11N6WuqYtZSvm+F776mB41wRZMhKP+hc34YdW+KmtYYK9iqvHSwo2k9FEH3fhGXvOPV6yz2IcSrfRUDg=="
     },
     "node_modules/de-indent": {
       "version": "1.0.2",

+ 1 - 0
package.json

@@ -15,6 +15,7 @@
     "@element-plus/icons-vue": "^2.3.1",
     "axios": "^1.6.7",
     "countup.js": "^2.8.0",
+    "dayjs": "^1.11.11",
     "echarts": "^5.5.0",
     "element-plus": "^2.6.1",
     "moment": "^2.30.1",

+ 35 - 0
src/api/serve/index.ts

@@ -17,6 +17,12 @@ enum API {
   // 获取近7天平均房价 接口地址
   AVGPRICE_URL = "/template/api/booking/QueryBookingAvgPrice",
 
+  // 获取用户评价体验指数 接口地址
+  COMMENTAVG_URL = "/template/api/booking/getCommentAvg",
+
+  // 获取用户评价列表数据 接口地址
+  COMMENTINFO_URL = "/template/api/booking/getCommentInfo",
+
   // 获取特产销售热榜top3数据 接口地址
   TOPBYAMOUNT_URL = "/template/api/speciality/getTopByAmount",
 
@@ -29,6 +35,9 @@ enum API {
   // 获取民宿列表数据 接口地址
   HOTELLIST_URL = "/template/api/hotel/QueryHotelList",
 
+  // 根据名称查询民宿列表 接口地址
+  HOTELLISTBYNAME_URL = "/template/api/hotel/QueryHotelListByName",
+
   // 获取停车场信息 接口地址
   PARKINGCOUNT_URL = "/template/api/parking/getParkingCount",
 
@@ -47,8 +56,14 @@ enum API {
   // 获取厕所分类数量 接口地址
   TOILETBASECOUNT_URL = "/template/api/toiletBase/getToiletBaseCount",
 
+  // 获取厕所数据监测数据 接口地址
+  TOILETREALDATA_URL = "/template/api/toiletBase/getToiletRealTime",
+
   // 获取厕所列表数据 接口地址
   TOILETBASEINFO_URL = "/template/api/toiletBase/getToiletBaseInfo",
+
+  // 根据id查询厕所实时数据 接口地址
+  TOILETDATABYID_URL = "/template/api/toiletBase/getToiletRealTimeById",
 }
 
 //获取住宿统计数据
@@ -71,6 +86,14 @@ export const reqGetOrderRank = () =>
 export const reqGetAvgPrice = () =>
   request.get(API.AVGPRICE_URL, { headers: { type: "local" } });
 
+// 获取用户评价体验指数
+export const reqGetCommentAvg = () =>
+  request.get(API.COMMENTAVG_URL, { headers: { type: "local" } });
+
+// 获取用户评价列表数据
+export const reqGetCommentInfo = (params: any) =>
+  request.get(API.COMMENTINFO_URL, { params, headers: { type: "local" } });
+
 // 获取特产销售热榜top3数据
 export const reqGetTopByAmount = () =>
   request.get(API.TOPBYAMOUNT_URL, { headers: { type: "local" } });
@@ -87,6 +110,10 @@ export const reqGetCateringType = () =>
 export const reqGetHotelList = (params: any) =>
   request.get(API.HOTELLIST_URL, { params, headers: { type: "local" } });
 
+// 根据名称查询民宿列表
+export const reqGetHotelListByName = (params: any) =>
+  request.get(API.HOTELLISTBYNAME_URL, { params, headers: { type: "local" } });
+
 // 获取停车场信息
 export const reqGetParkingCount = () =>
   request.get(API.PARKINGCOUNT_URL, { headers: { type: "local" } });
@@ -111,6 +138,14 @@ export const reqGetParkingInfoById = (params: any) =>
 export const reqGetToiletBaseCount = () =>
   request.get(API.TOILETBASECOUNT_URL, { headers: { type: "local" } });
 
+// 获取厕所数据监测数据
+export const reqGetToiletRealData = () =>
+  request.get(API.TOILETREALDATA_URL, { headers: { type: "local" } });
+
 // 获取厕所列表数据
 export const reqGetToiletBaseInfo = () =>
   request.get(API.TOILETBASEINFO_URL, { headers: { type: "local" } });
+
+// 根据id查询厕所实时数据
+export const reqGetToiletDataById = (params: any) =>
+  request.get(API.TOILETDATABYID_URL, { params, headers: { type: "local" } });

BIN
src/assets/images/88.png


+ 74 - 0
src/views/server/center/centerServer.vue

@@ -44,8 +44,18 @@
         placeholder="请输入民宿名称"
         :suffix-icon="Search"
         v-model="serachValue"
+        @input="handleChange"
       >
       </el-input>
+      <!-- 搜索结果区域 -->
+      <div
+        class="search_box"
+        v-for="item in searchList"
+        :key="item.id"
+        @click="handleClick(item)"
+      >
+        {{ item.hname }}
+      </div>
     </div>
   </div>
 
@@ -84,6 +94,15 @@
       @closeDialog="closeDialog"
     />
   </Transition>
+
+  <!-- 每一个民宿详情弹窗区域 -->
+  <Transition name="fade">
+    <HotelDetailDialogCenter
+      v-if="showDetailDialog"
+      :detailObj="detailObj"
+      @closeDialog="closeDialog"
+    />
+  </Transition>
 </template>
 
 <script setup lang="ts">
@@ -93,12 +112,15 @@ import HotelListDialog from "./hotelListDialog.vue";
 import ToiletDetailDialog from "./toiletDetailDialog.vue";
 import ParkingDetailDialog from "./parkingDetailDialog.vue";
 import PetrolDetailDialog from "./petrolDetailDialog.vue";
+import HotelDetailDialogCenter from "./hotelDetailDialogCenter.vue";
 import { Search } from "@element-plus/icons-vue";
 import img from "@/assets/images/49.png";
 import img2 from "@/assets/images/50.png";
 import img3 from "@/assets/images/51.png";
 import img4 from "@/assets/images/52.png";
 import { countUpNum } from "@/utils/countUpNum.ts";
+// 引入旅游服务相关的接口
+import { reqGetHotelListByName } from "@/api/serve/index";
 
 // 点位总计数据
 const pointCount = ref<number>(11);
@@ -135,8 +157,16 @@ const currentToilet = ref("");
 const currentParking = ref("");
 // 当前加油站
 const currentPetrol = ref("");
+
 // 搜索框绑定数据
 const serachValue = ref("");
+// 搜索出的民宿数组
+const searchList = ref<any>([]);
+
+// 每一个民宿详情弹窗显示隐藏控制
+const showDetailDialog = ref<boolean>(false);
+// 民宿详情数据
+const detailObj = ref({});
 
 // 民宿列表弹窗显示隐藏控制
 const showHotelList = ref<boolean>(false);
@@ -161,6 +191,27 @@ const init = () => {
   getCountUpNum();
 };
 
+// 民宿页面右上角搜索框回调
+const handleChange = async () => {
+  const res = await reqGetHotelListByName({
+    hName: serachValue.value,
+  });
+  // console.log(res);
+
+  searchList.value = res.data || [];
+};
+
+// 搜索框列表点击每一项触发的回调
+const handleClick = (item: any) => {
+  // console.log(item);
+  // 重置搜索框数据
+  searchList.value = [];
+  serachValue.value = "";
+
+  showDetailDialog.value = true;
+  detailObj.value = item;
+};
+
 // 让数字跳动
 const getCountUpNum = () => {
   nextTick(() => {
@@ -172,6 +223,10 @@ const getCountUpNum = () => {
 
 // 切换列表时的回调
 const changeIndex = (index: number, item: any) => {
+  // 重置搜索框数据
+  searchList.value = [];
+  serachValue.value = "";
+
   currentIndex.value = index;
   currentValue.value = item.title;
   if (item.title === "民宿") {
@@ -190,6 +245,10 @@ const clickMarker = (title: string, type: string) => {
   console.log(title, type);
   if (type === "民宿") {
     // console.log("民宿弹窗");
+    // 重置搜索框数据
+    searchList.value = [];
+    serachValue.value = "";
+
     currentTown.value = title;
     showHotelList.value = true;
   } else if (type === "厕所") {
@@ -212,6 +271,7 @@ const closeDialog = (data: boolean) => {
   showToilet.value = data;
   showParking.value = data;
   showPetrol.value = data;
+  showDetailDialog.value = data;
 };
 </script>
 
@@ -332,6 +392,20 @@ const closeDialog = (data: boolean) => {
         color: #fff;
       }
     }
+
+    .search_box {
+      padding-left: 20px;
+      width: 652px;
+      height: 75px;
+      line-height: 75px;
+      font-size: 26px;
+      cursor: pointer;
+      background-color: rgba($color: #02021c, $alpha: 0.8);
+
+      &:hover {
+        background-color: rgba($color: #fff, $alpha: 0.5);
+      }
+    }
   }
 }
 </style>

+ 14 - 22
src/views/server/center/hotelDetailDialog.vue

@@ -1,44 +1,39 @@
 <template>
   <div class="detail">
     <!-- 民宿名称区域 -->
-    <div class="name">{{ detailObj.title }}</div>
+    <div class="name">{{ detailObj.hname }}</div>
 
     <!-- 民宿信息区域 -->
     <div class="info">
-      <img :src="detailObj.url" />
+      <img :src="detailObj.cover_img" />
 
       <div class="info_detail">
         <div class="detail_top">
-          <div
-            class="top_address"
-            title="此处为民宿详细地址民宿详细地址此处为民宿详细地址民宿详细地址"
-          >
-            位置:此处为民宿详细地址民宿详细地址此处为民宿详细地址民宿详细地址
+          <div class="top_address" :title="detailObj.hposition">
+            位置:{{ detailObj.hposition }}
           </div>
-          <div>联系电话:13677985625</div>
+          <div>联系电话:{{ detailObj.corpn_phone }}</div>
         </div>
         <div class="detail_bottom">
-          <div class="bottom_box">床位数:250</div>
-          <div class="bottom_box">联系人:张三</div>
+          <div class="bottom_box">床位数:{{ detailObj.house }}</div>
+          <div class="bottom_box">联系人:{{ detailObj.corpn_name }}</div>
           <div class="bottom_box">
             星级:
-            <el-rate
-              v-model="rateValue"
-              :max="5"
-              disabled
-              disabled-void-color="transparent"
-            />
+            <span v-if="detailObj.type == 2">金宿级</span>
+            <span v-if="detailObj.type == 1">银宿级</span>
+            <span v-if="detailObj.type == 3">白金级</span>
+            <span v-if="!detailObj.type">暂无数据</span>
           </div>
-          <div>营业状态:营业中</div>
+          <div>营业状态:{{ detailObj.hstatus == 1 ? "营业中" : "休息" }}</div>
         </div>
       </div>
     </div>
 
     <!-- VR链接区域 -->
-    <div class="link">
+    <div class="link" v-if="detailObj.link_pro_url">
       VR链接:
       <div class="link_icon">
-        <el-link href="https://www.baidu.com" target="_blank">
+        <el-link :href="detailObj.link_pro_url" target="_blank">
           <el-icon size="38" color="#7DC0FF"><Link /></el-icon>
         </el-link>
       </div>
@@ -47,12 +42,9 @@
 </template>
 
 <script setup lang="ts">
-import { ref } from "vue";
 import { Link } from "@element-plus/icons-vue";
 
 defineProps(["detailObj"]);
-
-const rateValue = ref<number>(5);
 </script>
 
 <style lang="scss" scoped>

+ 177 - 0
src/views/server/center/hotelDetailDialogCenter.vue

@@ -0,0 +1,177 @@
+<template>
+  <div class="box">
+    <!-- 遮罩层区域 -->
+    <div class="mask" @click="handleClose"></div>
+    <!-- 弹窗内容区域 -->
+    <div class="detail">
+      <!-- 民宿名称区域 -->
+      <div class="name">{{ detailObj.hname }}</div>
+
+      <!-- 民宿信息区域 -->
+      <div class="info">
+        <img :src="detailObj.cover_img" />
+
+        <div class="info_detail">
+          <div class="detail_top">
+            <div class="top_address" :title="detailObj.hposition">
+              位置:{{ detailObj.hposition }}
+            </div>
+            <div>联系电话:{{ detailObj.corpn_phone }}</div>
+          </div>
+          <div class="detail_bottom">
+            <div class="bottom_box">床位数:{{ detailObj.house }}</div>
+            <div class="bottom_box">联系人:{{ detailObj.corpn_name }}</div>
+            <div class="bottom_box">
+              星级:
+              <span v-if="detailObj.type == 2">金宿级</span>
+              <span v-if="detailObj.type == 1">银宿级</span>
+              <span v-if="detailObj.type == 3">白金级</span>
+              <span v-if="!detailObj.type">暂无数据</span>
+            </div>
+            <div>
+              营业状态:{{ detailObj.hstatus == 1 ? "营业中" : "休息" }}
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <!-- VR链接区域 -->
+      <div class="link" v-if="detailObj.link_pro_url">
+        VR链接:
+        <div class="link_icon">
+          <el-link :href="detailObj.link_pro_url" target="_blank">
+            <el-icon size="38" color="#7DC0FF"><Link /></el-icon>
+          </el-link>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { Link } from "@element-plus/icons-vue";
+
+defineProps(["detailObj"]);
+const $emit = defineEmits(["closeDialog"]);
+
+// 点击关闭按钮回调
+const handleClose = () => {
+  $emit("closeDialog", false);
+};
+</script>
+
+<style lang="scss" scoped>
+.box {
+  z-index: 9999;
+  position: absolute;
+  top: -151px;
+  left: 0;
+  width: 7072px;
+  height: 1872px;
+  background-color: rgba($color: #000000, $alpha: 0.4);
+
+  .mask {
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: 7072px;
+    height: 1872px;
+  }
+
+  .detail {
+    position: absolute;
+    top: 642px;
+    left: 3110px;
+    width: 1024px;
+    height: 737px;
+    background-image: url(@/assets/images/54.png);
+    background-size: 100% 100%;
+
+    .name {
+      margin-top: 16px;
+      margin-left: 339px;
+      padding: 0 10px;
+      width: 357px;
+      height: 66px;
+      line-height: 66px;
+      text-align: center;
+      color: #8ec6fa;
+      font-size: 24px;
+      font-weight: bold;
+      overflow: hidden;
+      white-space: nowrap;
+      text-overflow: ellipsis;
+    }
+
+    .info {
+      position: relative;
+      margin-top: 38px;
+      margin-left: 62px;
+      width: 859px;
+      height: 485px;
+      border-radius: 10px;
+      overflow: hidden;
+
+      img {
+        width: 100%;
+        height: 100%;
+        object-fit: cover;
+      }
+
+      .info_detail {
+        position: absolute;
+        bottom: 0;
+        padding: 0 28px;
+        width: 859px;
+        height: 117px;
+        font-size: 20px;
+        background-color: rgba(0, 0, 0, 0.4);
+
+        .detail_top {
+          display: flex;
+          justify-content: space-between;
+          align-items: center;
+          height: 58px;
+
+          .top_address {
+            width: 540px;
+            overflow: hidden;
+            white-space: nowrap;
+            text-overflow: ellipsis;
+          }
+        }
+
+        .detail_bottom {
+          display: flex;
+          align-items: center;
+          height: 58px;
+
+          .bottom_box {
+            display: flex;
+            align-items: center;
+            margin-right: 48px;
+          }
+        }
+      }
+    }
+
+    .link {
+      display: flex;
+      align-items: center;
+      margin-left: 90px;
+      margin-top: 32px;
+      font-size: 27px;
+
+      .link_icon {
+        transform: rotateY(180deg);
+      }
+    }
+  }
+}
+
+::v-deep(.el-rate .el-rate__icon.is-active) {
+  margin: 0;
+  color: #7dc0ff;
+  font-size: 30px;
+}
+</style>

+ 32 - 6
src/views/server/center/hotelListDialog.vue

@@ -38,6 +38,9 @@
           <!-- 底部边框区域 -->
           <div class="item_line"></div>
         </div>
+
+        <!-- 没有数据时展示的区域 -->
+        <div class="list_nodata" v-if="!hotelList.length">暂无数据</div>
       </div>
 
       <!-- 分页器区域 -->
@@ -46,9 +49,11 @@
           v-model:current-page="currentPage"
           v-model:page-size="pageSize"
           background
+          hide-on-single-page
           layout="prev, pager, next, jumper"
           :total="total"
           :pager-count="5"
+          @current-change="handleCurrentChange"
         />
       </div>
 
@@ -77,7 +82,8 @@ const currentPage = ref<number>(1);
 // 每页多少条
 const pageSize = ref<number>(6);
 // 总条数
-const total = ref<number>(100);
+const total = ref<number>(0);
+
 // 每一个民宿详情弹窗显示隐藏控制
 const showDetailDialog = ref<boolean>(false);
 
@@ -94,23 +100,37 @@ onMounted(() => {
 
 // 获取民宿列表数据
 const getHotelList = async () => {
+  let town;
+  if ($props.currentTown === "雷公尖") {
+    town = "雷公尖乡";
+  } else if ($props.currentTown === "三爪仑") {
+    town = "三爪仑乡";
+  } else {
+    town = $props.currentTown;
+  }
   const res = await reqGetHotelList({
-    town: $props.currentTown,
+    town,
     hName: serachValue.value,
     pageNum: currentPage.value,
     pageSize: pageSize.value,
   });
   // console.log(res);
-  hotelList.value = res.data;
+  hotelList.value = res.data.hotelList || [];
+  total.value = res.data.total || 0;
 };
 
 // 输入框绑定值改变回调
-const handleChange = (v: any) => {
-  // console.log(v);
-  serachValue.value = v;
+const handleChange = () => {
   currentPage.value = 1;
   getHotelList();
 };
+
+// 当前页改变时触发的回调
+const handleCurrentChange = (v: number) => {
+  currentPage.value = v;
+  getHotelList();
+};
+
 // 点击关闭按钮回调
 const handleClose = () => {
   $emit("closeDialog", false);
@@ -250,6 +270,12 @@ const handleLookDetail = (item: any) => {
           background-size: 100% 100%;
         }
       }
+
+      .list_nodata {
+        margin-top: 200px;
+        text-align: center;
+        font-size: 26px;
+      }
     }
 
     .pagination {

+ 32 - 98
src/views/server/center/toiletDetailDialog.vue

@@ -1,71 +1,26 @@
 <template>
   <div class="container">
+    <!-- 遮罩层 -->
     <div class="mask" @click="handleClose"></div>
+
+    <!-- 内容弹窗区域 -->
     <div class="toilet">
       <!-- 名称区域 -->
       <div class="title" :title="currentToilet">{{ currentToilet }}</div>
 
       <!-- 信息盒子区域 -->
       <div class="info">
-        <!-- 男厕区域 -->
-        <div class="info_box">
-          <img class="box_img" src="@/assets/images/41.png" />
-          <div class="box_type">男厕</div>
-          <div class="box_num">50/1020</div>
-          <img class="box_line" src="@/assets/images/57.png" />
-          <div class="box_msg">
-            <div>入流量</div>
-            <div>1015</div>
-          </div>
-          <div class="box_msg">
-            <div>出流量</div>
-            <div>1015</div>
-          </div>
-          <div class="box_msg">
-            <div>驻留人数</div>
-            <div>1015</div>
-          </div>
-        </div>
-
-        <!-- 女厕区域 -->
-        <div class="info_box">
-          <img class="box_img" src="@/assets/images/42.png" />
-          <div class="box_type">女厕</div>
-          <div class="box_num">50/1020</div>
-          <img class="box_line" src="@/assets/images/57.png" />
-          <div class="box_msg">
-            <div>入流量</div>
-            <div>1015</div>
-          </div>
-          <div class="box_msg">
-            <div>出流量</div>
-            <div>1015</div>
-          </div>
-          <div class="box_msg">
-            <div>驻留人数</div>
-            <div>1015</div>
-          </div>
-        </div>
-
-        <!-- 无障碍厕所区域 -->
-        <div class="info_box">
-          <img class="box_img" src="@/assets/images/43.png" />
-          <div class="box_type">无障碍厕所</div>
-          <div class="box_num">50/1020</div>
-          <img class="box_line" src="@/assets/images/57.png" />
-          <div class="box_msg">
-            <div>入流量</div>
-            <div>1015</div>
-          </div>
-          <div class="box_msg">
-            <div>出流量</div>
-            <div>1015</div>
-          </div>
-          <div class="box_msg">
-            <div>驻留人数</div>
-            <div>1015</div>
-          </div>
+        <div class="info_box" :title="info?.address">
+          地址:{{ info?.address }}
         </div>
+        <div class="info_box">建设等级:{{ info?.level }}级</div>
+        <div class="info_box">无障碍厕所:{{ info?.barrierFree }}</div>
+        <div class="info_box">男厕所:{{ info?.man }}</div>
+        <div class="info_box">女厕所:{{ info?.woman }}</div>
+        <div class="info_box">男女通用侧位:{{ info?.unisex }}</div>
+        <div class="info_box">厕所面积:{{ info?.area }}㎡</div>
+        <div class="info_box">第三卫生间:{{ info?.third }}</div>
+        <div class="info_box">项目编号:{{ info?.number }}</div>
       </div>
 
       <!-- 关闭按钮区域 -->
@@ -88,7 +43,7 @@ const info = ref();
 onMounted(() => {
   // 匹配出当前厕所的信息
   info.value = toiletData.find((ele: any) => ele.title === props.currentToilet);
-  console.log(info.value);
+  // console.log(info.value);
 });
 
 // 点击关闭按钮回调
@@ -121,8 +76,8 @@ const handleClose = () => {
   .toilet {
     position: relative;
     width: 668px;
-    height: 401px;
-    background-image: url(@/assets/images/56.png);
+    height: 672px;
+    background-image: url(@/assets/images/88.png);
     background-size: 100% 100%;
 
     .title {
@@ -142,47 +97,26 @@ const handleClose = () => {
     }
 
     .info {
-      display: flex;
-      justify-content: space-evenly;
-      margin-top: 8px;
+      margin-top: 28px;
       margin-left: 37px;
       width: 604px;
-      height: 307px;
+      height: 565px;
 
       .info_box {
-        display: flex;
-        flex-direction: column;
-        align-items: center;
-        margin-top: 46px;
-        width: 127px;
-        font-size: 16px;
-        color: #fff;
-
-        .box_img {
-          width: 46px;
-          height: 46px;
-        }
-
-        .box_type {
-          margin-top: 10px;
-        }
-
-        .box_num {
-          margin-top: 10px;
-        }
-
-        .box_line {
-          margin-top: 10px;
-          width: 100%;
-          height: 4px;
-        }
-
-        .box_msg {
-          display: flex;
-          justify-content: space-between;
-          margin-top: 15px;
-          width: 100%;
-        }
+        margin: 0 auto 15px;
+        padding-left: 22px;
+        width: 530px;
+        height: 47px;
+        line-height: 47px;
+        font-size: 23px;
+        border-left: 2px solid #90cffc;
+        border-top: 0.1px dashed rgba(0, 186, 186, 0.3);
+        border-bottom: 1px dashed rgba(0, 186, 186, 0.3);
+        border-right: 1px dashed rgba(0, 186, 186, 0.3);
+        background-color: rgba(109, 161, 189, 0.21);
+        white-space: nowrap;
+        overflow: hidden;
+        text-overflow: ellipsis;
       }
     }
 

+ 27 - 4
src/views/server/left/average.vue

@@ -14,16 +14,39 @@
 <script setup lang="ts">
 import { ref, onMounted } from "vue";
 import * as Echarts from "echarts";
-import { getNearDay } from "@/utils/getNearDay.ts";
+// import { getNearDay } from "@/utils/getNearDay.ts";
+// 引入旅游服务相关的接口
+import { reqGetAvgPrice } from "@/api/serve/index";
 
 // 折线图DOM元素
 const lineChart = ref(null);
 
+// x轴数据
+const timeList = ref<any>([]);
+
+// y轴数据
+const valueList = ref<any>([]);
+
 onMounted(() => {
+  // 获取近7天平均房价
+  getAvgPrice();
+});
+
+// 获取近7天平均房价
+const getAvgPrice = async () => {
+  const res = await reqGetAvgPrice();
+  // console.log(res);
+
+  res.data.forEach((ele: any) => {
+    timeList.value.push(ele.endtime.slice(-2) + "日");
+    valueList.value.push(ele.priceavg);
+  });
+
   // 初始化折线图
   initLineChart();
-});
+};
 
+// 初始化折线图
 const initLineChart = () => {
   let myLineChart = Echarts.init(lineChart.value);
   // 折线图配置
@@ -49,7 +72,7 @@ const initLineChart = () => {
         fontSize: 16,
         margin: 20,
       },
-      data: getNearDay(7),
+      data: timeList.value,
     },
     yAxis: {
       type: "value",
@@ -71,7 +94,7 @@ const initLineChart = () => {
     },
     series: [
       {
-        data: [160, 199, 126, 116, 216, 516, 126, 316],
+        data: valueList.value,
         type: "line",
         smooth: true,
         color: "#1F92F6",

+ 40 - 24
src/views/server/left/evaluate.vue

@@ -20,13 +20,13 @@
           :key="index"
         >
           <div class="box_img">
-            <img
-              src="https://pic.rmb.bdstatic.com/daca09fd4974fe3361289d3306db4d63.jpeg"
-            />
+            <img :src="item.photo" />
           </div>
           <div class="box_info">
-            <div class="info_name">{{ item.name }}</div>
-            <div class="info_time">{{ item.time }}</div>
+            <div class="info_name">{{ item.comment_name }}</div>
+            <div class="info_time">
+              {{ dayjs(item.create_date).format("YYYY-MM-DD HH:mm:ss") }}
+            </div>
             <div class="info_detail">{{ item.content }}</div>
           </div>
         </div>
@@ -50,38 +50,53 @@
 import { ref, onMounted } from "vue";
 import * as Echarts from "echarts";
 import EvaluateDetailDialog from "./evaluateDetailDialog.vue";
+// 引入旅游服务相关的接口
+import { reqGetCommentAvg, reqGetCommentInfo } from "@/api/serve/index";
+import dayjs from "dayjs";
 
 // 仪表图DOM元素
 const gaugeChart = ref(null);
 
+// 用户体验指数
+const rate = ref();
+
 // 评价列表弹窗显示隐藏控制
 const showDetail = ref<boolean>(false);
 
-const evaluateList = ref([
-  {
-    name: "华志杰",
-    time: "2024-01-24 15:15:02",
-    content: "体验不错",
-  },
-  {
-    name: "刘子麟",
-    time: "2024-01-28 16:23:15",
-    content: "一般",
-  },
-  {
-    name: "夏文涛",
-    time: "2024-03-24 12:15:08",
-    content: "体验很好",
-  },
-]);
+// 用户评价列表
+const evaluateList = ref<any>([]);
 
 onMounted(() => {
+  // 获取用户评价体验指数
+  getCommentAvg();
+  // 获取用户评价列表数据
+  getCommentInfo();
+});
+
+// 获取用户评价体验指数
+const getCommentAvg = async () => {
+  const res = await reqGetCommentAvg();
+  // console.log(res);
+  rate.value = res.data[0].scoreavg;
+
   // 初始化仪表图
   initGaugeChart();
-});
+};
+
+// 获取用户评价列表数据
+const getCommentInfo = async () => {
+  const res = await reqGetCommentInfo({
+    pageNum: 1,
+    pageSize: 3,
+  });
+  // console.log(res);
+  evaluateList.value = res.data.commentInfoList;
+};
 
+// 初始化仪表图
 const initGaugeChart = () => {
   let myGaugeChart = Echarts.init(gaugeChart.value);
+
   // 仪表图配置
   const options = {
     series: [
@@ -154,13 +169,14 @@ const initGaugeChart = () => {
         },
         data: [
           {
-            value: 70,
+            value: parseInt(rate.value),
             name: "体验指数",
           },
         ],
       },
     ],
   };
+
   myGaugeChart.setOption(options);
 };
 

+ 94 - 82
src/views/server/left/evaluateDetailDialog.vue

@@ -19,6 +19,7 @@
           size="large"
           placeholder="请输入姓名"
           :suffix-icon="Search"
+          @change="handleSearch"
         />
 
         评价时间
@@ -29,7 +30,9 @@
           start-placeholder="请选择日期"
           end-placeholder="请选择日期"
           size="large"
+          value-format="YYYY-MM-DD HH:mm:ss"
           style="width: 575px; height: 75px; margin: 0 50px 0 30px"
+          @change="handleSearch"
         />
         舆情等级
         <el-select
@@ -37,12 +40,13 @@
           placeholder="全部"
           size="large"
           style="width: 575px; margin-left: 30px"
+          @change="handleSearch"
         >
           <el-option
             v-for="(item, index) in levelList"
             :key="index"
-            :label="item"
-            :value="item"
+            :label="item.text"
+            :value="item.value"
           />
         </el-select>
       </div>
@@ -61,19 +65,34 @@
               <el-image
                 class="table_img"
                 fit="contain"
-                :src="row.url"
-                :preview-src-list="[row.url]"
+                :src="row.photo"
+                :preview-src-list="[row.photo]"
                 hide-on-click-modal
                 preview-teleported
               ></el-image>
             </template>
           </el-table-column>
-          <el-table-column prop="name" label="姓名" align="center" />
-          <el-table-column prop="time" label="评价时间" align="center" />
-          <el-table-column prop="type" label="来源渠道" align="center" />
-          <el-table-column prop="order" label="订单号" align="center" />
+          <el-table-column prop="comment_name" label="姓名" align="center" />
+
+          <el-table-column label="评价时间" align="center">
+            <template #default="{ row }">
+              {{ dayjs(row.create_date).format("YYYY-MM-DD HH:mm:ss") }}
+            </template>
+          </el-table-column>
+
+          <el-table-column
+            prop="comment_status"
+            label="来源渠道"
+            align="center"
+          />
+          <el-table-column prop="booking_id" label="订单号" align="center" />
           <el-table-column prop="content" label="评价内容" align="center" />
-          <el-table-column prop="level" label="舆情等级" align="center" />
+
+          <el-table-column label="舆情等级" align="center">
+            <template #default="{ row }">
+              {{ row.comment_status == 0 ? "优" : "良" }}
+            </template>
+          </el-table-column>
           <el-table-column label="操作" align="center">
             <template #default="{ row }">
               <div class="table_btn" @click="lookDetail(row)">查看详情</div>
@@ -85,10 +104,13 @@
       <!-- 分页器区域 -->
       <div class="pagination">
         <el-pagination
+          hide-on-single-page
           background
           :pager-count="5"
           layout="prev, pager, next"
-          :total="1000"
+          v-model:current-page="currentPage"
+          v-model:page-size="pageSize"
+          :total="total"
         />
       </div>
 
@@ -105,100 +127,84 @@
 </template>
 
 <script setup lang="ts">
-import { ref } from "vue";
+import { ref, onMounted } from "vue";
 import { Search } from "@element-plus/icons-vue";
 import EvaluateMsgDialog from "./evaluateMsgDialog.vue";
+// 引入旅游服务相关的接口
+import { reqGetCommentInfo } from "@/api/serve/index";
+import dayjs from "dayjs";
 
 const $emit = defineEmits(["closeDialog"]);
 
+// 时间输入框绑定数据
 const nameValue = ref("");
 
+// 舆情等级筛选框绑定数据
 const levelValue = ref("");
 
-const timeRang = ref("");
+// 评价时间选择框绑定数据
+const timeRang = ref([]);
 
-const levelList = ref(["全部", "优", "良"]);
-
-const tableData = [
-  {
-    url: "https://pic.rmb.bdstatic.com/daca09fd4974fe3361289d3306db4d63.jpeg",
-    name: "华志杰",
-    time: "2024-10-01 11:39:30",
-    type: "线上特产",
-    order: "1222366444444",
-    content: "体验非常好",
-    level: "优",
-  },
-  {
-    url: "https://pic.rmb.bdstatic.com/daca09fd4974fe3361289d3306db4d63.jpeg",
-    name: "刘子麟",
-    time: "2024-10-01 11:39:30",
-    type: "线上特产",
-    order: "1222366444444",
-    content: "还行",
-    level: "良",
-  },
-  {
-    url: "https://pic.rmb.bdstatic.com/daca09fd4974fe3361289d3306db4d63.jpeg",
-    name: "夏文涛",
-    time: "2024-10-01 11:39:30",
-    type: "线上特产",
-    order: "1222366444444",
-    content: "体验非常好",
-    level: "优",
-  },
-  {
-    url: "https://pic.rmb.bdstatic.com/daca09fd4974fe3361289d3306db4d63.jpeg",
-    name: "朱秀平",
-    time: "2024-10-01 11:39:30",
-    type: "线上特产",
-    order: "1222366444444",
-    content: "还行",
-    level: "良",
-  },
-  {
-    url: "https://pic.rmb.bdstatic.com/daca09fd4974fe3361289d3306db4d63.jpeg",
-    name: "张海涛",
-    time: "2024-10-01 11:39:30",
-    type: "线上特产",
-    order: "1222366444444",
-    content: "体验非常好",
-    level: "优",
-  },
+// 舆情等级数组
+const levelList = ref([
   {
-    url: "https://pic.rmb.bdstatic.com/daca09fd4974fe3361289d3306db4d63.jpeg",
-    name: "张玉玲",
-    time: "2024-10-01 11:39:30",
-    type: "线上特产",
-    order: "1222366444444",
-    content: "还行",
-    level: "良",
+    text: "全部",
+    value: "",
   },
   {
-    url: "https://pic.rmb.bdstatic.com/daca09fd4974fe3361289d3306db4d63.jpeg",
-    name: "李荣",
-    time: "2024-10-01 11:39:30",
-    type: "线上特产",
-    order: "1222366444444",
-    content: "体验非常好",
-    level: "优",
+    text: "优",
+    value: 0,
   },
   {
-    url: "https://pic.rmb.bdstatic.com/daca09fd4974fe3361289d3306db4d63.jpeg",
-    name: "王晓雪",
-    time: "2024-10-01 11:39:30",
-    type: "线上特产",
-    order: "1222366444444",
-    content: "还行",
-    level: "良",
+    text: "良",
+    value: 1,
   },
-];
+]);
+
+// 每页多少条
+const pageSize = ref(8);
 
+// 当前页
+const currentPage = ref(1);
+
+// 总条数
+const total = ref(0);
+
+// 评价信息列表
+const tableData = ref([]);
+
+// 单个评价详细信息
 const showObj = ref({});
 
 // 评价详情弹窗显示隐藏控制
 const showMsg = ref<boolean>(false);
 
+onMounted(() => {
+  // 获取用户评价列表数据
+  getCommentInfo();
+});
+
+// 获取用户评价列表数据
+const getCommentInfo = async () => {
+  const res = await reqGetCommentInfo({
+    pageNum: currentPage.value,
+    pageSize: pageSize.value,
+    startTime: timeRang.value ? timeRang.value[0] : "",
+    endTime: timeRang.value ? timeRang.value[1] : "",
+    name: nameValue.value,
+    flag: levelValue.value,
+  });
+  // console.log(res);
+
+  if ((res as any).code == 200 && res.data.commentInfoList) {
+    tableData.value = res.data.commentInfoList;
+    total.value = res.data.total;
+  } else {
+    tableData.value = [];
+    total.value = 0;
+  }
+};
+
 // 点击关闭按钮回调
 const handleClose = () => {
   $emit("closeDialog", false);
@@ -214,6 +220,12 @@ const lookDetail = (row: any) => {
 const closeMsg = (data: boolean) => {
   showMsg.value = data;
 };
+
+// 筛选条件触发的回调
+const handleSearch = () => {
+  currentPage.value = 1;
+  getCommentInfo();
+};
 </script>
 
 <style lang="scss" scoped>

+ 12 - 8
src/views/server/left/evaluateMsgDialog.vue

@@ -5,9 +5,11 @@
     <!-- 关闭按钮区域 -->
     <div class="msg_close" @click="close"></div>
     <!-- 评价时间区域 -->
-    <div class="msg_box">评价时间:{{ showObj.time }}</div>
+    <div class="msg_box">
+      评价时间: {{ dayjs(showObj.create_date).format("YYYY-MM-DD HH:mm:ss") }}
+    </div>
     <!-- 姓名区域 -->
-    <div class="msg_box">姓名:{{ showObj.name }}</div>
+    <div class="msg_box">姓名:{{ showObj.comment_name }}</div>
 
     <!-- 头像区域 -->
     <div class="msg_box2">
@@ -15,10 +17,8 @@
       <el-image
         class="img"
         fit="cover"
-        src="https://pic.rmb.bdstatic.com/daca09fd4974fe3361289d3306db4d63.jpeg"
-        :preview-src-list="[
-          'https://pic.rmb.bdstatic.com/daca09fd4974fe3361289d3306db4d63.jpeg',
-        ]"
+        :src="showObj.photo"
+        :preview-src-list="[showObj.photo]"
         hide-on-click-modal
       ></el-image>
     </div>
@@ -26,10 +26,12 @@
     <div class="msg_box">来源渠道:{{ showObj.type }}</div>
 
     <!-- 订单号区域 -->
-    <div class="msg_box">订单号:{{ showObj.order }}</div>
+    <div class="msg_box">订单号:{{ showObj.booking_id }}</div>
 
     <!-- 舆情等级区域 -->
-    <div class="msg_box">舆情等级:{{ showObj.level }}</div>
+    <div class="msg_box">
+      舆情等级:{{ showObj.comment_status == 0 ? "优" : "良" }}
+    </div>
 
     <!-- 评价内容区域 -->
     <div class="msg_box3">
@@ -42,6 +44,8 @@
 </template>
 
 <script setup lang="ts">
+import dayjs from "dayjs";
+
 const $emit = defineEmits(["closeMsg"]);
 defineProps(["showObj"]);
 

+ 19 - 25
src/views/server/left/rank.vue

@@ -17,12 +17,12 @@
         ></el-table-column>
         <el-table-column
           label="名宿名称"
-          prop="name"
+          prop="hname"
           align="center"
         ></el-table-column>
         <el-table-column
           label="订单量"
-          prop="num"
+          prop="total"
           width="150"
           align="center"
         ></el-table-column>
@@ -32,31 +32,25 @@
 </template>
 
 <script setup lang="ts">
-// import { ref } from "vue";
+import { ref, onMounted } from "vue";
+// 引入旅游服务相关的接口
+import { reqGetOrderRank } from "@/api/serve/index";
 
 // 表格数据
-const tableData = [
-  {
-    name: "靖安园中源大酒店",
-    num: 62,
-  },
-  {
-    name: "靖安宝峰酒店",
-    num: 53,
-  },
-  {
-    name: "靖安桂庐山居",
-    num: 41,
-  },
-  {
-    name: "靖安国平酒店",
-    num: 22,
-  },
-  {
-    name: "588酒店",
-    num: 20,
-  },
-];
+const tableData = ref([]);
+
+onMounted(() => {
+  // 获取订单量排行数据
+  getOrderRank();
+});
+
+// 获取订单量排行数据
+const getOrderRank = async () => {
+  const res = await reqGetOrderRank();
+  // console.log(res);
+
+  tableData.value = res.data;
+};
 </script>
 
 <style lang="scss" scoped>

+ 27 - 4
src/views/server/left/trend.vue

@@ -14,18 +14,41 @@
 <script setup lang="ts">
 import { ref, onMounted } from "vue";
 import * as Echarts from "echarts";
-import { getNearDay } from "@/utils/getNearDay";
+// import { getNearDay } from "@/utils/getNearDay";
+// 引入旅游服务相关的接口
+import { reqGetBookTrend } from "@/api/serve/index";
 
 // 柱状图DOM元素
 const barChart = ref(null);
 
+// x轴数据
+const timeList = ref<any>([]);
+
+// y轴数据
+const valueList = ref<any>([]);
+
 onMounted(() => {
+  // 获取近7天房间预定趋势数据
+  getBookTrend();
+});
+
+// 获取近7天房间预定趋势数据
+const getBookTrend = async () => {
+  const res = await reqGetBookTrend();
+  // console.log(res);
+  res.data.forEach((ele: any) => {
+    timeList.value.push(ele.endtime.slice(-2) + "日");
+    valueList.value.push(ele.total);
+  });
+
   // 初始化柱状图
   initBarChart();
-});
+};
 
+// 初始化柱状图
 const initBarChart = () => {
   let myBarChart = Echarts.init(barChart.value);
+
   // 柱状图配置
   const options = {
     tooltip: {
@@ -46,7 +69,7 @@ const initBarChart = () => {
       axisLabel: {
         color: "#fff",
       },
-      data: getNearDay(7),
+      data: timeList.value,
     },
     yAxis: {
       type: "value",
@@ -59,7 +82,7 @@ const initBarChart = () => {
     },
     series: [
       {
-        data: [120, 200, 150, 80, 70, 110, 130],
+        data: valueList.value,
         type: "bar",
         barWidth: 35,
         showBackground: true,

+ 9 - 1
src/views/server/right/latrineData.vue

@@ -43,7 +43,7 @@ import { ref, onMounted } from "vue";
 import * as Echarts from "echarts";
 import { countUpNum } from "@/utils/countUpNum.ts";
 // 引入旅游服务相关的接口
-import { reqGetToiletBaseCount } from "@/api/serve/index";
+import { reqGetToiletBaseCount, reqGetToiletRealData } from "@/api/serve/index";
 
 // 厕所数量
 const num = ref<number>(48);
@@ -69,6 +69,8 @@ const total = ref(0);
 onMounted(() => {
   // 获取厕所分类数量
   getToiletBaseCount();
+  // 获取厕所数据监测数据
+  getToiletRealData();
 
   // 让数字跳动
   getCountUpNum();
@@ -117,6 +119,12 @@ const getToiletBaseCount = async () => {
   initPieChart();
 };
 
+// 获取厕所数据监测数据
+const getToiletRealData = async () => {
+  const res = await reqGetToiletRealData();
+  console.log(res);
+};
+
 // 初始化扇形图
 const initPieChart = () => {
   let myPieChart = Echarts.init(pieChart.value);

+ 12 - 2
src/views/server/right/latrineScene.vue

@@ -26,7 +26,6 @@
 
     <!-- 列表区域 -->
     <div class="list">
-      <!-- 每一个盒子区域 -->
       <!-- 男厕 -->
       <div class="list_box">
         <!-- 四个角的图标 -->
@@ -199,7 +198,7 @@
 <script setup lang="ts">
 import { ref, onMounted } from "vue";
 // 引入旅游服务相关的接口
-import { reqGetToiletBaseInfo } from "@/api/serve/index";
+import { reqGetToiletBaseInfo, reqGetToiletDataById } from "@/api/serve/index";
 
 // 当前选择的智慧厕所id
 const placeValue = ref();
@@ -219,6 +218,17 @@ const getToiletBaseInfo = async () => {
   options.value = res.data;
 
   placeValue.value = res.data[0].id;
+
+  // 根据id查询厕所实时数据
+  getToiletDataById();
+};
+
+// 根据id查询厕所实时数据
+const getToiletDataById = async () => {
+  const res = await reqGetToiletDataById({
+    toiletId: placeValue.value,
+  });
+  console.log(res);
 };
 
 // 筛选框切换回调