Browse Source

api数据对接

zq940222 6 months ago
parent
commit
04b9661d32
11 changed files with 416 additions and 273 deletions
  1. 0 0
      .env
  2. 1 0
      .env.development
  3. 5 1
      package.json
  4. 3 0
      src/App.vue
  5. 48 31
      src/components/AboutSection.vue
  6. 57 11
      src/components/DownloadSection.vue
  7. 101 75
      src/components/HomeSection.vue
  8. 68 154
      src/components/PricingSection.vue
  9. 110 0
      tsconfig.json
  10. 15 0
      vite.config.ts
  11. 8 1
      vue.config.js

+ 0 - 0
.env


+ 1 - 0
.env.development

@@ -0,0 +1 @@
+VITE_PROXY = [["/api","http://localhost:8090/api"]]

+ 5 - 1
package.json

@@ -7,9 +7,12 @@
         "build": "vue-cli-service build"
     },
     "dependencies": {
+        "axios": "^1.7.7",
         "core-js": "^3.8.2",
         "deepai": "^1.0.17",
         "firebase": "^7.24.0",
+        "tslint": "^6.1.3",
+        "typescript": "^5.6.2",
         "vue": "^2.6.12",
         "vue-youtube-embed": "^2.2.2",
         "vuetify": "^2.4.2"
@@ -19,6 +22,7 @@
         "@vue/cli-service": "~4.4.0",
         "sass": "~1.32.4",
         "sass-loader": "^8.0.0",
+        "vite": "^5.4.6",
         "vue-cli-plugin-vuetify": "^2.0.9",
         "vue-template-compiler": "^2.6.12",
         "vuetify-loader": "^1.3.0"
@@ -28,4 +32,4 @@
         "last 2 versions",
         "not dead"
     ]
-}
+}

+ 3 - 0
src/App.vue

@@ -94,5 +94,8 @@ export default {
       this.$vuetify.goTo(0);
     },
   },
+  mounted() {
+    document.title = 'canary website';
+  }
 };
 </script>

+ 48 - 31
src/components/AboutSection.vue

@@ -5,45 +5,19 @@
         <v-col cols="10">
           <v-row align="center" justify="center">
             <v-col cols="12" md="7">
-              <h1 class="font-weight-light display-2">Sobre</h1>
+              <h1 class="font-weight-light display-2">About Us</h1>
               <h1 class="font-weight-light display-1 mb-3">
-                Lorem ipsum dolor!
+                About our introduction!
               </h1>
               <v-row>
-                <v-col cols="12" class="d-flex align-center">
+                <v-col v-for="(aboutUs, i) in aboutUsData" :key="i" cols="12" class="d-flex align-center">
                   <v-img
                     src="@/assets/img/icon1.svg"
                     max-width="60px"
                     class="mr-4"
                   />
                   <p class="text-justify">
-                    Lorem ipsum dolor sit amet consectetur, adipisicing elit.
-                    Lorem ipsum dolor sit amet consectetur, adipisicing elit.
-                    Lorem ipsum dolor sit amet consectetur, adipisicing elit.
-                  </p>
-                </v-col>
-                <v-col cols="12" class="d-flex align-center">
-                  <v-img
-                    src="@/assets/img/icon2.svg"
-                    max-width="60px"
-                    class="mr-4"
-                  />
-                  <p class="text-justify">
-                    Lorem ipsum dolor sit amet consectetur, adipisicing elit.
-                    Lorem ipsum dolor sit amet consectetur, adipisicing elit.
-                    Lorem ipsum dolor sit amet consectetur, adipisicing elit.
-                  </p>
-                </v-col>
-                <v-col cols="12" class="d-flex align-center">
-                  <v-img
-                    src="@/assets/img/icon3.svg"
-                    max-width="60px"
-                    class="mr-4"
-                  />
-                  <p class="text-justify">
-                    Lorem ipsum dolor sit amet consectetur, adipisicing elit.
-                    Lorem ipsum dolor sit amet consectetur, adipisicing elit.
-                    Lorem ipsum dolor sit amet consectetur, adipisicing elit.
+                    {{ aboutUs.content }}
                   </p>
                 </v-col>
               </v-row>
@@ -68,9 +42,52 @@
 }
 </style>
 <script>
+import axios from "axios";
+
 export default {
   data: () => ({
-    model: null,
+    // model: null,
+    aboutUsData:[],
+
   }),
+  created() {
+    this.getAboutUsData();
+  },
+  methods: {
+    getAboutUsData() {
+      const websiteCode = this.extractSubstring(window.location.pathname);
+      let userWebsiteId = "";
+      axios.get("/api/website/template/getWebsiteByWebsiteCode", {
+        params: {
+          websiteCode: websiteCode,
+        }
+      }).then(response => {
+        if (response.data.code === 200) {
+          userWebsiteId = response.data.data.id;
+          axios.get("/api/website/template/aboutUs", {
+            params: {
+              userWebsiteId: userWebsiteId,
+            }
+          }).then(response => {
+            this.aboutUsData = response.data.data;
+          })
+        }})
+       .catch(error => {
+          console.error('Error fetching about us data:', error);
+        });
+    },
+    extractSubstring(str) {
+      const startIndex = str.indexOf('/');
+      if (startIndex !== -1) {
+        const endIndex = str.indexOf('/', startIndex + 1);
+        if (endIndex !== -1) {
+          return str.substring(startIndex + 1, endIndex - 1);
+        } else {
+          return str.substring(startIndex + 1);
+        }
+      }
+      return ''; // 如果没有找到匹配,返回空字符串
+    }
+  }
 }
 </script>

+ 57 - 11
src/components/DownloadSection.vue

@@ -5,21 +5,13 @@
         <v-col cols="10">
           <v-row align="center" justify="center">
             <v-col sm="4" class="hidden-xs-only">
-              <v-img src="@/assets/img/ill2.svg" class="d-block ml-auto mr-auto" max-width="350px" />
+              <v-img src="@/assets/img/ill2.svg" class="d-block ml-auto mr-auto" max-width="350px"/>
             </v-col>
             <v-col cols="12" sm="8" class="white--text text-left">
-              <h1 class="font-weight-light display-2 mb-2">Baixar Demonstração</h1>
+              <h1 class="font-weight-light display-2 mb-2">About Company</h1>
               <h1 class="font-weight-light">
-                Lorem ipsum dolor sit amet consectetur adipisicing elit. Iste ex
-                animi quod laboriosam vel blanditiis labore alias, aliquid,
-                tempora repellendus non.
+                {{ companyData.intro }}
               </h1>
-              <v-btn rounded outlined href="https://github.com/Joabsonlg/Landing-Page" target="_blank" large color="white" class="mt-4">
-                <v-icon class="mr-2">
-                  mdi-github
-                </v-icon>
-                Git Hub
-              </v-btn>
             </v-col>
           </v-row>
         </v-col>
@@ -27,7 +19,61 @@
     </v-container>
   </section>
 </template>
+<script>
+import axios from 'axios';
 
+export default {
+  data() {
+    return {
+      companyData: {
+        intro: ""
+      }
+    }
+  },
+  created() {
+    this.getCompanyData();
+  },
+  methods: {
+    getCompanyData() {
+      const websiteCode = this.extractSubstring(window.location.pathname);
+      let userWebsiteId = "";
+      axios.get("/api/website/template/getWebsiteByWebsiteCode", {
+        params: {
+          websiteCode: websiteCode,
+        }
+      }).then(response => {
+        if (response.data.code === 200) {
+          userWebsiteId = response.data.data.id;
+          axios.get("/api/website/template/company", {
+            params: {
+              userWebsiteId: userWebsiteId,
+            }
+          }).then(response => {
+            if (response.data.data !== null) {
+              this.companyData = response.data.data;
+            }
+          })
+        }
+      })
+          .catch(error => {
+            console.error('Error fetching company data:', error);
+          });
+    },
+    extractSubstring(str) {
+      const startIndex = str.indexOf('/');
+      if (startIndex !== -1) {
+        const endIndex = str.indexOf('/', startIndex + 1);
+        if (endIndex !== -1) {
+          return str.substring(startIndex + 1, endIndex - 1);
+        } else {
+          return str.substring(startIndex + 1);
+        }
+      }
+      return ''; // 如果没有找到匹配,返回空字符串
+    }
+  }
+}
+</script>
 <style scoped>
 #download {
   background-image: url("~@/assets/img/bgDownload.jpg");

+ 101 - 75
src/components/HomeSection.vue

@@ -1,76 +1,32 @@
 <template>
-  <section id="hero">
+  <section id="home">
     <v-parallax dark src="@/assets/img/bgHero.jpg" height="750">
       <v-row align="center" justify="center">
         <v-col cols="10">
           <v-row align="center" justify="center">
             <v-col cols="12" md="6" xl="8">
-              <h1 class="display-2 font-weight-bold mb-4">Vuetify.js</h1>
+              <h1 class="display-2 font-weight-bold mb-4">{{ homeData.title }}</h1>
               <h1 class="font-weight-light">
-                Lorem ipsum dolor sit amet consectetur <br />
-                adipisicing elit. Maiores porro voluptatibus <br />
-                delectus nam optio harum!
+                {{ homeData.content }}
               </h1>
               <v-btn
-                rounded
-                outlined
-                large
-                dark
-                @click="$vuetify.goTo('#features')"
-                class="mt-5"
+                  rounded
+                  outlined
+                  large
+                  dark
+                  @click="$vuetify.goTo('#features')"
+                  class="mt-5"
               >
                 Saiba mais
                 <v-icon class="ml-2">mdi-arrow-down</v-icon>
               </v-btn>
-              <div class="video d-flex align-center py-4">
-                <a @click.stop="dialog = true" class="playBut">
-                  <svg
-                    version="1.1"
-                    xmlns="http://www.w3.org/2000/svg"
-                    xmlns:xlink="http://www.w3.org/1999/xlink"
-                    xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
-                    x="0px"
-                    y="0px"
-                    width="60px"
-                    height="60px"
-                    viewBox="0 0 213.7 213.7"
-                    enable-background="new 0 0 213.7 213.7"
-                    xml:space="preserve"
-                  >
-                    <polygon
-                      class="triangle"
-                      id="XMLID_18_"
-                      fill="none"
-                      stroke-width="7"
-                      stroke-linecap="round"
-                      stroke-linejoin="round"
-                      stroke-miterlimit="10"
-                      points="73.5,62.5 148.5,105.8 73.5,149.1 "
-                    />
-
-                    <circle
-                      class="circle"
-                      id="XMLID_17_"
-                      fill="none"
-                      stroke-width="7"
-                      stroke-linecap="round"
-                      stroke-linejoin="round"
-                      stroke-miterlimit="10"
-                      cx="106.8"
-                      cy="106.8"
-                      r="103.3"
-                    />
-                  </svg>
-                </a>
-                <p class="subheading ml-2 mb-0">Assista o vídeo</p>
-              </div>
             </v-col>
-            <v-col cols="12" md="6" xl="4" class="hidden-sm-and-down"> </v-col>
+            <v-col cols="12" md="6" xl="4" class="hidden-sm-and-down"></v-col>
           </v-row>
         </v-col>
       </v-row>
       <div class="svg-border-waves text-white">
-        <v-img src="@/assets/img/borderWaves.svg" />
+        <v-img src="@/assets/img/borderWaves.svg"/>
       </div>
     </v-parallax>
     <v-container fluid id="features" class="mt-2">
@@ -95,28 +51,28 @@
               </h1>
             </v-col> -->
             <v-col
-              cols="12"
-              sm="4"
-              class="text-center"
-              v-for="(feature, i) in features"
-              :key="i"
+                cols="12"
+                sm="4"
+                class="text-center"
+                v-for="(feature, i) in productsData"
+                :key="i"
             >
               <v-hover v-slot:default="{ hover }">
                 <v-card
-                  class="card"
-                  shaped
-                  :elevation="hover ? 10 : 4"
-                  :class="{ up: hover }"
+                    class="card"
+                    shaped
+                    :elevation="hover ? 10 : 4"
+                    :class="{ up: hover }"
                 >
                   <v-img
-                    :src="feature.img"
-                    max-width="100px"
-                    class="d-block ml-auto mr-auto"
-                    :class="{ 'zoom-efect': hover }"
+                      :src="getImageUrl(i)"
+                      max-width="100px"
+                      class="d-block ml-auto mr-auto"
+                      :class="{ 'zoom-efect': hover }"
                   ></v-img>
-                  <h1 class="font-weight-regular">{{ feature.title }}</h1>
-                  <h4 class="font-weight-regular subtitle-1">
-                    {{ feature.text }}
+                  <h1 class="font-weight-regular">{{ feature.name }}</h1>
+                  <h4 class="font-weight-regular subtitle-1 text-container">
+                    {{ feature.description }}
                   </h4>
                 </v-card>
               </v-hover>
@@ -128,19 +84,21 @@
     <v-dialog v-model="dialog" max-width="640px">
       <v-card>
         <youtube
-          :video-id="videoId"
-          @ready="ready"
-          @playing="playing"
+            :video-id="videoId"
+            @ready="ready"
+            @playing="playing"
         ></youtube>
       </v-card>
     </v-dialog>
     <div class="svg-border-waves">
-      <img src="~@/assets/img/wave2.svg" />
+      <img src="~@/assets/img/wave2.svg"/>
     </div>
   </section>
 </template>
 
 <script>
+import axios from 'axios';
+
 export default {
   data() {
     return {
@@ -178,6 +136,14 @@ export default {
           text: "Lorem ipsum dolor sit amet consectetur adipisicing elit.",
         },
       ],
+      homeData: {},
+      userWebsiteId: "",
+      productsData: [],
+      images: [
+        require("@/assets/img/icon1.png"),
+        require("@/assets/img/icon2.png"),
+        require("@/assets/img/icon3.png"),
+      ]
     };
   },
   watch: {
@@ -187,6 +153,9 @@ export default {
       }
     },
   },
+  created() {
+    this.getWebsiteData();
+  },
   methods: {
     ready(event) {
       this.player = event.target;
@@ -207,6 +176,55 @@ export default {
     pause() {
       this.player.pauseVideo();
     },
+    getImageUrl(index) {
+      // 使用 index 对 3 取余数,循环分配图片
+      return this.images[index % this.images.length];
+    },
+    getWebsiteData() {
+      const websiteCode = this.extractSubstring(window.location.pathname);
+      let userWebsiteId = "";
+      axios.get("/api/website/template/getWebsiteByWebsiteCode", {
+        params: {
+          websiteCode: websiteCode,
+        }
+      }).then(response => {
+        if (response.data.code === 200) {
+          userWebsiteId = response.data.data.id;
+          this.getHomeTitleAndContent(userWebsiteId)
+          this.getProductsTitleAndContent(userWebsiteId)
+        }
+      });
+    },
+    getHomeTitleAndContent(userWebsiteId) {
+      axios.get("/api/website/template/home", {
+        params: {
+          userWebsiteId: userWebsiteId,
+        },
+      }).then(response => {
+        this.homeData = response.data.data;
+      })
+    },
+    getProductsTitleAndContent(userWebsiteId) {
+      axios.get("/api/website/template/products", {
+        params: {
+          userWebsiteId: userWebsiteId,
+        },
+      }).then(response => {
+        this.productsData = response.data.data;
+      })
+    },
+    extractSubstring(str) {
+      const startIndex = str.indexOf('/');
+      if (startIndex !== -1) {
+        const endIndex = str.indexOf('/', startIndex + 1);
+        if (endIndex !== -1) {
+          return str.substring(startIndex + 1, endIndex - 1);
+        } else {
+          return str.substring(startIndex + 1);
+        }
+      }
+      return ''; // 如果没有找到匹配,返回空字符串
+    }
   },
 };
 </script>
@@ -284,6 +302,7 @@ export default {
 #hero {
   z-index: 0;
 }
+
 .svg-border-waves img {
   position: absolute;
   bottom: 0;
@@ -316,6 +335,13 @@ export default {
   transform: translateY(-20px);
   transition: 0.5s ease-out;
 }
+.text-container {
+  display: -webkit-box;
+  -webkit-line-clamp: 3; /* 显示三行 */
+  -webkit-box-orient: vertical;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
 </style>
 
 <style>

+ 68 - 154
src/components/PricingSection.vue

@@ -7,59 +7,25 @@
             <h1 class="text-center pt-6 font-weight-light display-2">Blog</h1>
             <v-divider class="my-6"></v-divider>
             <v-row class="text-center">
-              <v-col class="col-12 col-sm-6 col-md-4">
+              <v-col v-for="(blog, i) in blogData" :key="i" class="col-12 col-sm-6 col-md-4">
                 <div class="flex-center">
                   <v-card-text>
                     <div class="flex-center">
                       <div class="circle1">
                         <div class="circle2">
-                          <v-img src="~@/assets/img/paperplane.svg"></v-img>
+                          <v-img
+                              :src="getImageUrl(i)" alt="Image"
+                          ></v-img>
                         </div>
                       </div>
                     </div>
-                    <div class="text--disabled text-uppercase text-h5 my-2">Básico</div>
+                    <div class="text--disabled text-uppercase text-h5 my-2 text-container">{{ blog.title }}</div>
                     <v-divider class="my-2"/>
-                    <div class="text-uppercase blue--text">Domínios personalizados</div>
-                  </v-card-text>
-                  <v-divider style="margin-right: -23px" vertical v-if="this.$vuetify.breakpoint.smAndUp"></v-divider>
-                </div>
-                <v-divider class="mx-4" v-if="!this.$vuetify.breakpoint.smAndUp"></v-divider>
-              </v-col>
-              <v-col class="col-12 col-sm-6 col-md-4">
-                <div class="flex-center">
-                  <v-card-text>
-                    <div class="flex-center">
-                      <div class="circle1">
-                        <div class="circle2">
-                          <v-img src="~@/assets/img/airplane.svg"/>
-                        </div>
-                      </div>
-                    </div>
-                    <div class="text--disabled text-uppercase text-h5 my-2">Padrão</div>
-                    <v-divider class="my-2"/>
-                    <div class="text-uppercase blue--text">Domínios personalizados</div>
-                  </v-card-text>
-                  <v-divider style="margin-right: -23px" vertical v-if="this.$vuetify.breakpoint.mdAndUp"></v-divider>
-                </div>
-                <v-divider class="mx-4" v-if="!this.$vuetify.breakpoint.smAndUp"></v-divider>
-              </v-col>
-              <v-col class="col-12 col-md-4">
-                <v-divider v-if="this.$vuetify.breakpoint.smOnly" class="mx-4"></v-divider>
-
-                <div class="flex-center">
-                  <v-card-text>
-                    <div class="flex-center">
-                      <div class="circle1">
-                        <div class="circle2">
-                          <v-img src="~@/assets/img/aeroplane.svg"/>
-                        </div>
-                      </div>
-                    </div>
-                    <div class="text--disabled text-uppercase text-h5 my-2">Empresarial</div>
-                    <v-divider class="my-2"/>
-                    <div class="text-uppercase blue--text">Domínios personalizados</div>
+                    <div class="text-uppercase blue--text text-container">{{ blog.content }}</div>
                   </v-card-text>
+<!--                  <v-divider style="margin-right: -23px" vertical v-if="this.$vuetify.breakpoint.smAndUp"></v-divider>-->
                 </div>
+<!--                <v-divider class="mx-4" v-if="!this.$vuetify.breakpoint.smAndUp"></v-divider>-->
               </v-col>
             </v-row>
           </v-card>
@@ -179,124 +145,30 @@ svg {
 section {
   position: relative;
 }
+.text-container {
+  display: -webkit-box;
+  -webkit-line-clamp: 3; /* 显示三行 */
+  -webkit-box-orient: vertical;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
 </style>
 
 <script>
+import axios from "axios";
+
 export default {
   data: () => ({
-    planos: [
-      {
-        title: "Básico",
-        price: "R$100,00",
-        img: "f1.png",
-        features: [
-          {
-            icon: {
-              text: "mdi-check",
-              color: "success",
-            },
-            text: "Feature 1",
-          },
-          {
-            icon: {
-              text: "mdi-check",
-              color: "success",
-            },
-            text: "Feature 2",
-          },
-          {
-            icon: {
-              text: "mdi-cancel",
-              color: "red",
-            },
-            text: "Feature 3",
-          },
-          {
-            icon: {
-              text: "mdi-cancel",
-              color: "red",
-            },
-            text: "Feature 4",
-          },
-        ],
-      },
-      {
-        title: "Padrão",
-        price: "R$150,00",
-        img: "f2.png",
-        features: [
-          {
-            icon: {
-              text: "mdi-check",
-              color: "success",
-            },
-            text: "Feature 1",
-            color: "success",
-          },
-          {
-            icon: {
-              text: "mdi-check",
-              color: "success",
-            },
-            text: "Feature 2",
-          },
-          {
-            icon: {
-              text: "mdi-check",
-              color: "success",
-            },
-            text: "Feature 3",
-            color: "success",
-          },
-          {
-            icon: {
-              text: "mdi-cancel",
-              color: "red",
-            },
-            text: "Feature 4",
-          },
-        ],
-      },
-      {
-        title: "Premium",
-        price: "R$250,00",
-        img: "f3.png",
-        features: [
-          {
-            icon: {
-              text: "mdi-check",
-              color: "success",
-            },
-            text: "Feature 1",
-            color: "success",
-          },
-          {
-            icon: {
-              text: "mdi-check",
-              color: "success",
-            },
-            text: "Feature 2",
-          },
-          {
-            icon: {
-              text: "mdi-check",
-              color: "success",
-            },
-            text: "Feature 3",
-            color: "success",
-          },
-          {
-            icon: {
-              text: "mdi-check",
-              color: "success",
-            },
-            text: "Feature 4",
-            color: "success",
-          },
-        ],
-      },
-    ],
+    blogData: [],
+    images:[
+      require(`@/assets/img/paperplane.svg`),
+      require(`@/assets/img/airplane.svg`),
+      require(`@/assets/img/aeroplane.svg`)
+    ]
   }),
+  created() {
+    this.getBlogData();
+  },
   computed: {
     size() {
       const size = {md: "large", xl: "x-large"}[
@@ -305,5 +177,47 @@ export default {
       return size ? {[size]: true} : {};
     }
   },
+  methods: {
+    getImageUrl(index) {
+      // 使用 index 对 3 取余数,循环分配图片
+      return this.images[index % this.images.length];
+    },
+    getBlogData() {
+      const websiteCode = this.extractSubstring(window.location.pathname);
+      let userWebsiteId = "";
+      axios.get("/api/website/template/getWebsiteByWebsiteCode", {
+        params: {
+          websiteCode: websiteCode,
+        }
+      }).then(response => {
+        if (response.data.code === 200) {
+          userWebsiteId = response.data.data.id;
+          axios.get("/api/website/template/blogs", {
+            params: {
+              userWebsiteId: userWebsiteId,
+            }
+          }).then(response => {
+            this.blogData = response.data.data;
+            console.log(this.blogData);
+          })
+        }
+      })
+          .catch(error => {
+            console.error('Error fetching about us data:', error);
+          });
+    },
+    extractSubstring(str) {
+      const startIndex = str.indexOf('/');
+      if (startIndex !== -1) {
+        const endIndex = str.indexOf('/', startIndex + 1);
+        if (endIndex !== -1) {
+          return str.substring(startIndex + 1, endIndex - 1);
+        } else {
+          return str.substring(startIndex + 1);
+        }
+      }
+      return ''; // 如果没有找到匹配,返回空字符串
+    }
+  },
 };
 </script>

+ 110 - 0
tsconfig.json

@@ -0,0 +1,110 @@
+{
+  "compilerOptions": {
+    /* Visit https://aka.ms/tsconfig to read more about this file */
+
+    /* Projects */
+    // "incremental": true,                              /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
+    // "composite": true,                                /* Enable constraints that allow a TypeScript project to be used with project references. */
+    // "tsBuildInfoFile": "./.tsbuildinfo",              /* Specify the path to .tsbuildinfo incremental compilation file. */
+    // "disableSourceOfProjectReferenceRedirect": true,  /* Disable preferring source files instead of declaration files when referencing composite projects. */
+    // "disableSolutionSearching": true,                 /* Opt a project out of multi-project reference checking when editing. */
+    // "disableReferencedProjectLoad": true,             /* Reduce the number of projects loaded automatically by TypeScript. */
+
+    /* Language and Environment */
+    "target": "es2016",                                  /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
+    // "lib": [],                                        /* Specify a set of bundled library declaration files that describe the target runtime environment. */
+    // "jsx": "preserve",                                /* Specify what JSX code is generated. */
+    // "experimentalDecorators": true,                   /* Enable experimental support for legacy experimental decorators. */
+    // "emitDecoratorMetadata": true,                    /* Emit design-type metadata for decorated declarations in source files. */
+    // "jsxFactory": "",                                 /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
+    // "jsxFragmentFactory": "",                         /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
+    // "jsxImportSource": "",                            /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
+    // "reactNamespace": "",                             /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
+    // "noLib": true,                                    /* Disable including any library files, including the default lib.d.ts. */
+    // "useDefineForClassFields": true,                  /* Emit ECMAScript-standard-compliant class fields. */
+    // "moduleDetection": "auto",                        /* Control what method is used to detect module-format JS files. */
+
+    /* Modules */
+    "module": "commonjs",                                /* Specify what module code is generated. */
+    // "rootDir": "./",                                  /* Specify the root folder within your source files. */
+    // "moduleResolution": "node10",                     /* Specify how TypeScript looks up a file from a given module specifier. */
+    // "baseUrl": "./",                                  /* Specify the base directory to resolve non-relative module names. */
+    // "paths": {},                                      /* Specify a set of entries that re-map imports to additional lookup locations. */
+    // "rootDirs": [],                                   /* Allow multiple folders to be treated as one when resolving modules. */
+    // "typeRoots": [],                                  /* Specify multiple folders that act like './node_modules/@types'. */
+    // "types": [],                                      /* Specify type package names to be included without being referenced in a source file. */
+    // "allowUmdGlobalAccess": true,                     /* Allow accessing UMD globals from modules. */
+    // "moduleSuffixes": [],                             /* List of file name suffixes to search when resolving a module. */
+    // "allowImportingTsExtensions": true,               /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
+    // "resolvePackageJsonExports": true,                /* Use the package.json 'exports' field when resolving package imports. */
+    // "resolvePackageJsonImports": true,                /* Use the package.json 'imports' field when resolving imports. */
+    // "customConditions": [],                           /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
+    // "noUncheckedSideEffectImports": true,             /* Check side effect imports. */
+    // "resolveJsonModule": true,                        /* Enable importing .json files. */
+    // "allowArbitraryExtensions": true,                 /* Enable importing files with any extension, provided a declaration file is present. */
+    // "noResolve": true,                                /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
+
+    /* JavaScript Support */
+    // "allowJs": true,                                  /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
+    // "checkJs": true,                                  /* Enable error reporting in type-checked JavaScript files. */
+    // "maxNodeModuleJsDepth": 1,                        /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
+
+    /* Emit */
+    // "declaration": true,                              /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
+    // "declarationMap": true,                           /* Create sourcemaps for d.ts files. */
+    // "emitDeclarationOnly": true,                      /* Only output d.ts files and not JavaScript files. */
+    // "sourceMap": true,                                /* Create source map files for emitted JavaScript files. */
+    // "inlineSourceMap": true,                          /* Include sourcemap files inside the emitted JavaScript. */
+    // "noEmit": true,                                   /* Disable emitting files from a compilation. */
+    // "outFile": "./",                                  /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
+    // "outDir": "./",                                   /* Specify an output folder for all emitted files. */
+    // "removeComments": true,                           /* Disable emitting comments. */
+    // "importHelpers": true,                            /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
+    // "downlevelIteration": true,                       /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
+    // "sourceRoot": "",                                 /* Specify the root path for debuggers to find the reference source code. */
+    // "mapRoot": "",                                    /* Specify the location where debugger should locate map files instead of generated locations. */
+    // "inlineSources": true,                            /* Include source code in the sourcemaps inside the emitted JavaScript. */
+    // "emitBOM": true,                                  /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
+    // "newLine": "crlf",                                /* Set the newline character for emitting files. */
+    // "stripInternal": true,                            /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
+    // "noEmitHelpers": true,                            /* Disable generating custom helper functions like '__extends' in compiled output. */
+    // "noEmitOnError": true,                            /* Disable emitting files if any type checking errors are reported. */
+    // "preserveConstEnums": true,                       /* Disable erasing 'const enum' declarations in generated code. */
+    // "declarationDir": "./",                           /* Specify the output directory for generated declaration files. */
+
+    /* Interop Constraints */
+    // "isolatedModules": true,                          /* Ensure that each file can be safely transpiled without relying on other imports. */
+    // "verbatimModuleSyntax": true,                     /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
+    // "isolatedDeclarations": true,                     /* Require sufficient annotation on exports so other tools can trivially generate declaration files. */
+    // "allowSyntheticDefaultImports": true,             /* Allow 'import x from y' when a module doesn't have a default export. */
+    "esModuleInterop": true,                             /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
+    // "preserveSymlinks": true,                         /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
+    "forceConsistentCasingInFileNames": true,            /* Ensure that casing is correct in imports. */
+
+    /* Type Checking */
+    "strict": true,                                      /* Enable all strict type-checking options. */
+    // "noImplicitAny": true,                            /* Enable error reporting for expressions and declarations with an implied 'any' type. */
+    // "strictNullChecks": true,                         /* When type checking, take into account 'null' and 'undefined'. */
+    // "strictFunctionTypes": true,                      /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
+    // "strictBindCallApply": true,                      /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
+    // "strictPropertyInitialization": true,             /* Check for class properties that are declared but not set in the constructor. */
+    // "strictBuiltinIteratorReturn": true,              /* Built-in iterators are instantiated with a 'TReturn' type of 'undefined' instead of 'any'. */
+    // "noImplicitThis": true,                           /* Enable error reporting when 'this' is given the type 'any'. */
+    // "useUnknownInCatchVariables": true,               /* Default catch clause variables as 'unknown' instead of 'any'. */
+    // "alwaysStrict": true,                             /* Ensure 'use strict' is always emitted. */
+    // "noUnusedLocals": true,                           /* Enable error reporting when local variables aren't read. */
+    // "noUnusedParameters": true,                       /* Raise an error when a function parameter isn't read. */
+    // "exactOptionalPropertyTypes": true,               /* Interpret optional property types as written, rather than adding 'undefined'. */
+    // "noImplicitReturns": true,                        /* Enable error reporting for codepaths that do not explicitly return in a function. */
+    // "noFallthroughCasesInSwitch": true,               /* Enable error reporting for fallthrough cases in switch statements. */
+    // "noUncheckedIndexedAccess": true,                 /* Add 'undefined' to a type when accessed using an index. */
+    // "noImplicitOverride": true,                       /* Ensure overriding members in derived classes are marked with an override modifier. */
+    // "noPropertyAccessFromIndexSignature": true,       /* Enforces using indexed accessors for keys declared using an indexed type. */
+    // "allowUnusedLabels": true,                        /* Disable error reporting for unused labels. */
+    // "allowUnreachableCode": true,                     /* Disable error reporting for unreachable code. */
+
+    /* Completeness */
+    // "skipDefaultLibCheck": true,                      /* Skip type checking .d.ts files that are included with TypeScript. */
+    "skipLibCheck": true                                 /* Skip type checking all .d.ts files. */
+  }
+}

+ 15 - 0
vite.config.ts

@@ -0,0 +1,15 @@
+import { defineConfig } from 'vite';
+
+export default defineConfig({
+  server: {
+    port: 3200,
+    cors: false,
+    proxy: {
+      '/api': {
+        target: 'http://127.0.0.1:8090',
+        changeOrigin: true,
+        // rewrite: (path) => path.replace(/^\/api/, ''),
+      },
+    },
+  },
+})

+ 8 - 1
vue.config.js

@@ -3,6 +3,13 @@ module.exports = {
     "vuetify"
   ],
   devServer: {
-    port: 3200
+    port: 3200,
+    proxy: {
+      '/api': {// 匹配所有以 '/api1'开头的请求路径
+        target: 'http://localhost:8090',// 代理目标的基础路径
+        changeOrigin: true,
+        // pathRewrite: {'^/api1': ''}
+      },
+    }
   }
 }