Przeglądaj źródła

feat: init project

gemercheung 1 rok temu
commit
8a8dc66256

+ 24 - 0
.gitignore

@@ -0,0 +1,24 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+dist
+dist-ssr
+*.local
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+.DS_Store
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?

+ 3 - 0
.vscode/extensions.json

@@ -0,0 +1,3 @@
+{
+  "recommendations": ["Vue.volar", "Vue.vscode-typescript-vue-plugin"]
+}

+ 7 - 0
README.md

@@ -0,0 +1,7 @@
+# Vue 3 + Vite
+
+This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
+
+## Recommended IDE Setup
+
+- [VS Code](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).

+ 13 - 0
index.html

@@ -0,0 +1,13 @@
+<!doctype html>
+<html lang="en">
+  <head>
+    <meta charset="UTF-8" />
+    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <title></title>
+  </head>
+  <body>
+    <div id="app"></div>
+    <script type="module" src="/src/main.js"></script>
+  </body>
+</html>

+ 27 - 0
package.json

@@ -0,0 +1,27 @@
+{
+  "name": "qiushou-kiosk",
+  "private": true,
+  "version": "0.0.0",
+  "type": "module",
+  "scripts": {
+    "dev": "vite",
+    "build": "vite build",
+    "preview": "vite preview"
+  },
+  "dependencies": {
+    "@vueuse/core": "^10.6.1",
+    "@vueuse/integrations": "^10.6.1",
+    "axios": "^1.6.2",
+    "naive-ui": "^2.35.0",
+    "pinia": "^2.1.7",
+    "vue": "^3.3.8",
+    "vue-router": "^4.0.13"
+  },
+  "devDependencies": {
+    "@vitejs/plugin-vue": "^4.5.0",
+    "sass": "^1.69.5",
+    "unplugin-auto-import": "^0.16.7",
+    "unplugin-vue-components": "^0.25.2",
+    "vite": "^5.0.0"
+  }
+}

Plik diff jest za duży
+ 1362 - 0
pnpm-lock.yaml


Plik diff jest za duży
+ 1 - 0
public/vite.svg


+ 22 - 0
src/App.vue

@@ -0,0 +1,22 @@
+<template>
+  <n-config-provider :theme="theme" :themeOverrides="themeOverrides">
+    <router-view />
+  </n-config-provider>
+</template>
+
+<script setup>
+import { ref } from "vue";
+import { themeOverrides } from "./theme/override.js";
+import { darkTheme } from "naive-ui";
+const theme = ref(null);
+</script>
+
+<style scoped>
+.layout,
+.n-config-provider {
+  height: 100%;
+}
+.n-layout-scroll-container {
+  overflow: hidden;
+}
+</style>

+ 1 - 0
src/assets/vue.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>

+ 68 - 0
src/components/infoBox.vue

@@ -0,0 +1,68 @@
+<template>
+  <n-card class="info-box">
+    <template #cover>
+      <img :src="cover" />
+    </template>
+    <!-- <div class="cover" :style="{ backgroundImage: `url(${cover})` }"></div> -->
+    <div class="info-line">
+      <div class="title">{{ title }}</div>
+      <div class="time-line">
+        <span> {{ time }}</span>
+        <div class="see-more" @click="$router.push(`/info-detail/${id}`)">
+          查看
+        </div>
+      </div>
+    </div>
+  </n-card>
+</template>
+<script setup>
+defineOptions({
+  name: "info-box",
+});
+
+defineProps({
+  id: {
+    type: [Number, String],
+    default: () => NaN,
+  },
+  title: {
+    type: [String, undefined],
+    default: () => "",
+  },
+  cover: {
+    type: [String, undefined],
+    default: () => "",
+  },
+  time: {
+    type: [String, undefined],
+    default: () => "",
+  },
+});
+</script>
+<style lang="scss" scoped>
+.n-card.info-box {
+  padding: 10px;
+  --n-padding-left: 0 !important;
+  --n-padding-bottom: 0 !important;
+  .cover {
+    min-height: 250px;
+    background-color: gray;
+  }
+  .title {
+    font-size: 28px;
+  }
+  .info-line {
+    display: flex;
+    flex-direction: column;
+    .time-line {
+      width: 100%;
+      flex: 1;
+      display: flex;
+      justify-content: space-between;
+      .see-more {
+        cursor: pointer;
+      }
+    }
+  }
+}
+</style>

+ 28 - 0
src/components/noticeBox.vue

@@ -0,0 +1,28 @@
+<template>
+  <n-card :title="title">
+    {{ content }}
+    <template #footer>
+      {{ time }}
+    </template>
+  </n-card>
+</template>
+<script setup>
+defineOptions({
+  name: "notice-box",
+});
+
+defineProps({
+  title: {
+    type: String,
+    default: () => "",
+  },
+  content: {
+    type: String,
+    default: () => "",
+  },
+  time: {
+    type: String,
+    default: () => "",
+  },
+});
+</script>

+ 9 - 0
src/main.js

@@ -0,0 +1,9 @@
+import { createApp } from "vue";
+import router from "./router";
+import "./style.css";
+import App from "./App.vue";
+import { setupStore } from "./store";
+
+const app = createApp(App);
+setupStore(app);
+app.use(router).mount("#app");

+ 69 - 0
src/router/index.js

@@ -0,0 +1,69 @@
+import { createRouter, createWebHistory } from "vue-router";
+
+const routes = [
+  {
+    path: "/",
+    name: "home",
+    component: () => import("@/views/home.vue"),
+    meta: {
+      title: "首页",
+    },
+  },
+  {
+    path: "/info",
+    name: "info",
+    component: () => import("@/views/info.vue"),
+    meta: {
+      title: "场馆资讯",
+    },
+  },
+
+  {
+    path: "/guide",
+    name: "Guide",
+    component: () => import("@/views/guide.vue"),
+    meta: {
+      title: "展厅导览",
+    },
+  },
+
+  {
+    path: "/collect",
+    name: "collect",
+    component: () => import("@/views/collect.vue"),
+    meta: {
+      title: "馆藏精品",
+    },
+  },
+  {
+    path: "/survey",
+    name: "survey",
+    component: () => import("@/views/survey.vue"),
+    meta: {
+      title: "问卷调查",
+    },
+  },
+  {
+    path: "/feedback",
+    name: "feedback",
+    component: () => import("@/views/feedback.vue"),
+    meta: {
+      title: "留言反馈",
+    },
+  },
+  {
+    path: "/info-detail/:id",
+    name: "infoDetail",
+    component: () => import("@/views/info-detail.vue"),
+    meta: {
+      title: "留言反馈",
+    },
+  },
+];
+
+const router = createRouter({
+  history: createWebHistory(),
+  routes,
+});
+
+export default router;

+ 8 - 0
src/store/index.js

@@ -0,0 +1,8 @@
+import { createPinia } from "pinia";
+
+const store = createPinia();
+export function setupStore(app) {
+  app.use(store);
+}
+
+export { store };

+ 29 - 0
src/store/info.js

@@ -0,0 +1,29 @@
+import { defineStore } from "pinia";
+import axios from "axios";
+import { useAxios } from "@vueuse/integrations/useAxios";
+
+const instance = axios.create({
+  baseURL: "https://test.4dkankan.com/api",
+});
+
+export const useInfoStore = defineStore({
+  id: "info",
+  state: () => {
+    return {
+      exhibition: [],
+      activity: [],
+      news: [],
+      notices: [],
+    };
+  },
+  getters: {},
+  actions: {
+    getData() {
+      const { data, isFinished } = useAxios(
+        "/test",
+        { method: "get" },
+        instance
+      );
+    },
+  },
+});

+ 39 - 0
src/style.css

@@ -0,0 +1,39 @@
+:root {
+  /* --n-color: rgba(255, 255, 255, 0.83);
+  --n-text-color: rgba(255, 255, 255, 0.83); */
+}
+
+html,
+body,
+#app {
+  width: 100%;
+  height: 100%;
+  margin: 0;
+  padding: 0;
+}
+
+.back {
+  cursor: pointer;
+}
+
+/* Scroll bar stylings */
+::-webkit-scrollbar {
+  width: 10px;
+  height: 10px;
+}
+
+/* Track */
+::-webkit-scrollbar-track {
+  background: var(--lightestgrey);
+}
+
+/* Handle */
+::-webkit-scrollbar-thumb {
+  background: #888;
+  border-radius: 5px;
+}
+
+/* Handle on hover */
+::-webkit-scrollbar-thumb:hover {
+  background: #555;
+}

+ 12 - 0
src/theme/override.js

@@ -0,0 +1,12 @@
+export const themeOverrides = {
+  common: {
+    fontFamily:
+      'v-sans, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"',
+    fontFamilyMono:
+      "v-mono, SFMono-Regular, Menlo, Consolas, Courier, monospace",
+    fontWeight: "400",
+
+    primaryColor: "#ffffff",
+    // primaryColorHover: "#7fe7c4",
+  },
+};

+ 160 - 0
src/views/collect.vue

@@ -0,0 +1,160 @@
+<template>
+  <div class="main">
+    <div class="content">
+      <div class="left">
+        <n-tabs type="line">
+          <template #prefix><span class="meta-title">场馆资讯</span> </template>
+          <n-tab-pane name="展览" tab="展览">
+            <!-- <n-scrollbar style="height: 100%" trigger="none"> -->
+            <n-grid x-gap="12" y-gap="12" :cols="3" class="tab-grid">
+              <template v-for="item in 16">
+                <n-gi>
+                  <infoBox
+                    title="卡片"
+                    cover="https://07akioni.oss-cn-beijing.aliyuncs.com/07akioni.jpeg"
+                    time="2023-01-02"
+                  />
+                </n-gi>
+              </template>
+            </n-grid>
+          </n-tab-pane>
+          <n-tab-pane name="活动" tab="活动">
+            <n-grid x-gap="12" y-gap="12" :cols="3" class="tab-grid">
+              <template v-for="item in 16">
+                <n-gi>
+                  <infoBox
+                    title="卡片"
+                    cover="https://07akioni.oss-cn-beijing.aliyuncs.com/07akioni.jpeg"
+                    time="2023-01-02"
+                  />
+                </n-gi>
+              </template>
+            </n-grid>
+          </n-tab-pane>
+          <n-tab-pane name="新闻" tab="新闻">
+            <n-grid x-gap="12" y-gap="12" :cols="3" class="tab-grid">
+              <template v-for="item in 16">
+                <n-gi>
+                  <infoBox
+                    title="卡片"
+                    cover="https://07akioni.oss-cn-beijing.aliyuncs.com/07akioni.jpeg"
+                    time="2023-01-02"
+                  />
+                </n-gi>
+              </template>
+            </n-grid>
+          </n-tab-pane>
+          <n-tab-pane name="通知" tab="通知">
+            <n-grid y-gap="20" :cols="1" class="tab-grid">
+              <template v-for="item in 16">
+                <n-gi>
+                  <notice-box
+                    title="这是一段标题这是一段标题"
+                    content="这是一段摘要这是一段摘要这是一段摘要这是一段摘要这是一段摘要这是一段摘要这是一段摘要这是一段摘要这是一段摘要这是一段摘要这是一段摘要这是一段摘要这是一段摘要这是一段摘要这是一段摘要这是一段摘要这是一段摘要这是一段摘要这是一段..."
+                    time="2023-01-02"
+                  />
+                </n-gi>
+              </template>
+            </n-grid>
+          </n-tab-pane>
+        </n-tabs>
+      </div>
+      <div class="right">
+        <div class="logo"></div>
+        <div class="back" @click="$router.push('/')"></div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { onMounted } from "vue";
+import { useFullscreen } from "@vueuse/core";
+import infoBox from "../components/infoBox";
+import noticeBox from "../components/noticeBox";
+import { useInfoStore } from "../store/info";
+
+const { isFullscreen, enter, exit, toggle } = useFullscreen();
+const InfoStore = useInfoStore();
+
+onMounted(() => {
+  InfoStore.getData();
+});
+</script>
+
+<style>
+.main {
+  --main-left-background: grey;
+  --main-right-background: rgba(0, 0, 0, 0.8);
+  --logo-width: 100px;
+  --go-home-width: 60px;
+  --logo-background-color: rgba(0, 0, 0, 0.5);
+  --left-content-padding: 50px;
+  --right-content-padding: 50px;
+}
+</style>
+
+<style lang="scss" scoped>
+.main {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+  overflow-y: hidden;
+}
+.meta-title {
+  font-size: 34px;
+  padding-right: 50px;
+}
+.head {
+  width: 100%;
+  height: 60px;
+}
+.content {
+  flex: 1;
+  display: flex;
+  width: 100%;
+  height: 100%;
+  flex-direction: row;
+  overflow: hidden;
+}
+.left {
+  flex: 1;
+  background-color: var(--main-left-background);
+  padding: var(--left-content-padding);
+  .n-tabs {
+    height: 100%;
+    overflow: hidden;
+    :deep(.n-tab-pane) {
+      overflow-y: scroll;
+    }
+  }
+}
+.n-tabs {
+  --n-tab-font-size: 26px !important;
+}
+.right {
+  flex: 0 0 10%;
+  min-width: 120px;
+  /* max-width: 120px; */
+  height: calc(100% - var(--right-content-padding) * 2);
+  background-color: var(--main-right-background);
+  display: flex;
+  padding: 50px 0;
+  flex-direction: column;
+  align-items: center;
+  justify-content: space-between;
+  .logo {
+    width: var(--logo-width);
+    height: var(--logo-width);
+    border-radius: 50%;
+    background-color: var(--logo-background-color);
+  }
+  .back {
+    width: var(--go-home-width);
+    height: var(--go-home-width);
+    border-radius: 50%;
+    background-color: var(--logo-background-color);
+  }
+}
+</style>

+ 36 - 0
src/views/feedback.vue

@@ -0,0 +1,36 @@
+<template>
+  <div class="main">
+    <div class="content">
+      
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { useFullscreen } from "@vueuse/core";
+const { isFullscreen, enter, exit, toggle } = useFullscreen();
+console.log("isFullscreen", isFullscreen);
+</script>
+<style>
+.main {
+  --main-left-background: #e2caa3;
+  --main-right-background: #910000;
+}
+</style>
+
+<style scoped>
+.main {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  flex-direction: row;
+}
+.left {
+  flex: 0 0 70%;
+  background-color: var(--main-left-background);
+}
+.right {
+  flex: 0 0 30%;
+  background-color: var(--main-right-background);
+}
+</style>

+ 34 - 0
src/views/guide.vue

@@ -0,0 +1,34 @@
+<template>
+  <div class="main">
+    
+  </div>
+</template>
+
+<script setup>
+import { useFullscreen } from "@vueuse/core";
+const { isFullscreen, enter, exit, toggle } = useFullscreen();
+console.log("isFullscreen", isFullscreen);
+</script>
+<style>
+.main {
+  --main-left-background: #e2caa3;
+  --main-right-background: #910000;
+}
+</style>
+
+<style scoped>
+.main {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  flex-direction: row;
+}
+.left {
+  flex: 0 0 70%;
+  background-color: var(--main-left-background);
+}
+.right {
+  flex: 0 0 30%;
+  background-color: var(--main-right-background);
+}
+</style>

+ 89 - 0
src/views/home.vue

@@ -0,0 +1,89 @@
+<template>
+  <div class="main">
+    <div class="left">
+      <!-- post -->
+      <n-carousel
+        direction="vertical"
+        dot-placement="right"
+        show-arrow
+        style="width: 100%; height: 100%"
+        autoplay
+      >
+        <img
+          class="carousel-img"
+          style="width: 100%; height: 100%; object-fit: cover"
+          src="https://naive-ui.oss-cn-beijing.aliyuncs.com/carousel-img/carousel1.jpeg"
+        />
+        <img
+          class="carousel-img"
+          style="width: 100%; height: 100%; object-fit: cover"
+          src="https://naive-ui.oss-cn-beijing.aliyuncs.com/carousel-img/carousel2.jpeg"
+        />
+        <img
+          class="carousel-img"
+          style="width: 100%; height: 100%; object-fit: cover"
+          src="https://naive-ui.oss-cn-beijing.aliyuncs.com/carousel-img/carousel3.jpeg"
+        />
+        <img
+          class="carousel-img"
+          style="width: 100%; height: 100%; object-fit: cover"
+          src="https://naive-ui.oss-cn-beijing.aliyuncs.com/carousel-img/carousel4.jpeg"
+        />
+      </n-carousel>
+    </div>
+    <div class="right">
+      <n-space class="navi" justify="center">
+        <n-button class="btn" @click="push('/info')"> 场馆资讯</n-button>
+        <n-button class="btn" @click="push('/guide')"> 展厅导览</n-button>
+        <n-button class="btn" @click="push('/collect')"> 馆藏精品 </n-button>
+        <n-button class="btn" @click="push('/survey')"> 问卷调查</n-button>
+        <n-button class="btn" @click="push('/feedback')"> 留言反馈</n-button>
+      </n-space>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { useFullscreen } from "@vueuse/core";
+import { useRoute, useRouter } from "vue-router";
+
+const { push } = useRouter();
+
+const { isFullscreen, enter, exit, toggle } = useFullscreen();
+console.log("isFullscreen", isFullscreen);
+</script>
+<style>
+.main {
+  --main-left-background: #e2caa3;
+  --main-right-background: #910000;
+}
+</style>
+
+<style scoped>
+.main {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  flex-direction: row;
+}
+
+.left {
+  flex: 1 1 70%;
+  background-color: var(--main-left-background);
+}
+.right {
+  flex: 0 0 30%;
+  max-width: 400px;
+  background-color: var(--main-right-background);
+}
+.navi {
+  display: flex;
+  align-items: center;
+  margin-top: 30px;
+}
+:deep(.btn) {
+  color: white;
+  font-size: 26px;
+  padding: 30px 50px;
+}
+</style>

+ 102 - 0
src/views/info-detail.vue

@@ -0,0 +1,102 @@
+<template>
+  <div class="main">
+    <div class="content">
+      <div class="left">
+
+      </div>
+      <div class="right">
+        <div class="logo"></div>
+            <div class="back" @click="$router.push('/')"></div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { onMounted } from "vue";
+// import { useFullscreen } from "@vueuse/core";
+import { useInfoStore } from "../store/info";
+
+const InfoStore = useInfoStore();
+
+onMounted(() => {
+  //   InfoStore.getData();
+});
+</script>
+
+<style>
+.main {
+  --main-left-background: grey;
+  --main-right-background: rgba(0, 0, 0, 0.8);
+  --logo-width: 100px;
+  --go-home-width: 60px;
+  --logo-background-color: rgba(0, 0, 0, 0.5);
+  --left-content-padding: 50px;
+  --right-content-padding: 50px;
+}
+</style>
+
+<style lang="scss" scoped>
+.main {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+  overflow-y: hidden;
+}
+.meta-title {
+  font-size: 34px;
+  padding-right: 50px;
+}
+.head {
+  width: 100%;
+  height: 60px;
+}
+.content {
+  flex: 1;
+  display: flex;
+  width: 100%;
+  height: 100%;
+  flex-direction: row;
+  overflow: hidden;
+}
+.left {
+  flex: 1;
+  background-color: var(--main-left-background);
+  padding: var(--left-content-padding);
+  .n-tabs {
+    height: 100%;
+    overflow: hidden;
+    :deep(.n-tab-pane) {
+      overflow-y: scroll;
+    }
+  }
+}
+.n-tabs {
+  --n-tab-font-size: 26px !important;
+}
+.right {
+  flex: 0 0 10%;
+  min-width: 120px;
+  /* max-width: 120px; */
+  height: calc(100% - var(--right-content-padding) * 2);
+  background-color: var(--main-right-background);
+  display: flex;
+  padding: 50px 0;
+  flex-direction: column;
+  align-items: center;
+  justify-content: space-between;
+  .logo {
+    width: var(--logo-width);
+    height: var(--logo-width);
+    border-radius: 50%;
+    background-color: var(--logo-background-color);
+  }
+  .back {
+    width: var(--go-home-width);
+    height: var(--go-home-width);
+    border-radius: 50%;
+    background-color: var(--logo-background-color);
+  }
+}
+</style>

+ 164 - 0
src/views/info.vue

@@ -0,0 +1,164 @@
+<template>
+  <div class="main">
+    <!-- <div class="head"></div> -->
+    <!-- <Teleport to=".n-tabs-nav"> xxx </Teleport> -->
+
+    <div class="content">
+      <div class="left">
+        <n-tabs type="line">
+          <template #prefix><span class="meta-title">场馆资讯</span> </template>
+          <n-tab-pane name="展览" tab="展览">
+            <!-- <n-scrollbar style="height: 100%" trigger="none"> -->
+            <n-grid x-gap="12" y-gap="12" :cols="3" class="tab-grid">
+              <template v-for="(_, index) in 16">
+                <n-gi>
+                  <infoBox
+                    :id="index + 1"
+                    title="卡片"
+                    cover="https://07akioni.oss-cn-beijing.aliyuncs.com/07akioni.jpeg"
+                    time="2023-01-02"
+                  />
+                </n-gi>
+              </template>
+            </n-grid>
+          </n-tab-pane>
+          <n-tab-pane name="活动" tab="活动">
+            <n-grid x-gap="12" y-gap="12" :cols="3" class="tab-grid">
+              <template v-for="item in 16">
+                <n-gi>
+                  <infoBox
+                    title="卡片"
+                    cover="https://07akioni.oss-cn-beijing.aliyuncs.com/07akioni.jpeg"
+                    time="2023-01-02"
+                  />
+                </n-gi>
+              </template>
+            </n-grid>
+          </n-tab-pane>
+          <n-tab-pane name="新闻" tab="新闻">
+            <n-grid x-gap="12" y-gap="12" :cols="3" class="tab-grid">
+              <template v-for="item in 16">
+                <n-gi>
+                  <infoBox
+                    title="卡片"
+                    cover="https://07akioni.oss-cn-beijing.aliyuncs.com/07akioni.jpeg"
+                    time="2023-01-02"
+                  />
+                </n-gi>
+              </template>
+            </n-grid>
+          </n-tab-pane>
+          <n-tab-pane name="通知" tab="通知">
+            <n-grid y-gap="20" :cols="1" class="tab-grid">
+              <template v-for="item in 16">
+                <n-gi>
+                  <notice-box
+                    title="这是一段标题这是一段标题"
+                    content="这是一段摘要这是一段摘要这是一段摘要这是一段摘要这是一段摘要这是一段摘要这是一段摘要这是一段摘要这是一段摘要这是一段摘要这是一段摘要这是一段摘要这是一段摘要这是一段摘要这是一段摘要这是一段摘要这是一段摘要这是一段摘要这是一段..."
+                    time="2023-01-02"
+                  />
+                </n-gi>
+              </template>
+            </n-grid>
+          </n-tab-pane>
+        </n-tabs>
+      </div>
+      <div class="right">
+        <div class="logo"></div>
+        <div class="back" @click="$router.push('/')"></div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { onMounted } from "vue";
+import { useFullscreen } from "@vueuse/core";
+import infoBox from "../components/infoBox";
+import noticeBox from "../components/noticeBox";
+import { useInfoStore } from "../store/info";
+
+const { isFullscreen, enter, exit, toggle } = useFullscreen();
+const InfoStore = useInfoStore();
+
+onMounted(() => {
+  InfoStore.getData();
+});
+</script>
+
+<style>
+.main {
+  --main-left-background: grey;
+  --main-right-background: rgba(0, 0, 0, 0.8);
+  --logo-width: 100px;
+  --go-home-width: 60px;
+  --logo-background-color: rgba(0, 0, 0, 0.5);
+  --left-content-padding: 50px;
+  --right-content-padding: 50px;
+}
+</style>
+
+<style lang="scss" scoped>
+.main {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+  overflow-y: hidden;
+}
+.meta-title {
+  font-size: 34px;
+  padding-right: 50px;
+}
+.head {
+  width: 100%;
+  height: 60px;
+}
+.content {
+  flex: 1;
+  display: flex;
+  width: 100%;
+  height: 100%;
+  flex-direction: row;
+  overflow: hidden;
+}
+.left {
+  flex: 1;
+  background-color: var(--main-left-background);
+  padding: var(--left-content-padding);
+  .n-tabs {
+    height: 100%;
+    overflow: hidden;
+    :deep(.n-tab-pane) {
+      overflow-y: scroll;
+    }
+  }
+}
+.n-tabs {
+  --n-tab-font-size: 26px !important;
+}
+.right {
+  flex: 0 0 10%;
+  min-width: 120px;
+  /* max-width: 120px; */
+  height: calc(100% - var(--right-content-padding) * 2);
+  background-color: var(--main-right-background);
+  display: flex;
+  padding: 50px 0;
+  flex-direction: column;
+  align-items: center;
+  justify-content: space-between;
+  .logo {
+    width: var(--logo-width);
+    height: var(--logo-width);
+    border-radius: 50%;
+    background-color: var(--logo-background-color);
+  }
+  .back {
+    width: var(--go-home-width);
+    height: var(--go-home-width);
+    border-radius: 50%;
+    background-color: var(--logo-background-color);
+  }
+}
+</style>

+ 32 - 0
src/views/survey.vue

@@ -0,0 +1,32 @@
+<template>
+  <div class="main">feedback</div>
+</template>
+
+<script setup>
+import { useFullscreen } from "@vueuse/core";
+const { isFullscreen, enter, exit, toggle } = useFullscreen();
+console.log("isFullscreen", isFullscreen);
+</script>
+<style>
+.main {
+  --main-left-background: #e2caa3;
+  --main-right-background: #910000;
+}
+</style>
+
+<style scoped>
+.main {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  flex-direction: row;
+}
+.left {
+  flex: 0 0 70%;
+  background-color: var(--main-left-background);
+}
+.right {
+  flex: 0 0 30%;
+  background-color: var(--main-right-background);
+}
+</style>

+ 35 - 0
vite.config.js

@@ -0,0 +1,35 @@
+import { defineConfig } from "vite";
+import vue from "@vitejs/plugin-vue";
+import path from "path";
+import AutoImport from "unplugin-auto-import/vite";
+import Components from "unplugin-vue-components/vite";
+import { NaiveUiResolver } from "unplugin-vue-components/resolvers";
+
+// https://vitejs.dev/config/
+export default defineConfig({
+  plugins: [
+    vue(),
+    AutoImport({
+      imports: [
+        "vue",
+        {
+          "naive-ui": [
+            "useDialog",
+            "useMessage",
+            "useNotification",
+            "useLoadingBar",
+          ],
+        },
+      ],
+    }),
+    Components({
+      resolvers: [NaiveUiResolver()],
+    }),
+  ],
+  resolve: {
+    alias: {
+      "@": path.resolve(__dirname, "src"),
+    },
+    extensions: [".mjs", ".js", ".ts", ".jsx", ".tsx", ".json", ".vue"],
+  },
+});