panqiuyao 9 ماه پیش
والد
کامیت
54ae761e07

+ 3 - 0
frontend/.env

@@ -0,0 +1,3 @@
+NODE_ENV=localhost
+API_PATH = /api
+API_PAY_PATH = /pay

+ 2 - 2
frontend/.env.development

@@ -1,2 +1,2 @@
-VITE_TITLE=""
-VITE_GO_URL="http://localhost:8081"
+NODE_ENV=development
+API_HOST = //dev2.pubdata.cn

+ 3 - 2
frontend/.env.production

@@ -1,2 +1,3 @@
-VITE_TITLE=""
-VITE_GO_URL="http://www.test.com"
+NODE_ENV=production
+API_HOST = //dev.valimart.net
+

+ 20 - 2
frontend/.gitignore

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

+ 5 - 0
frontend/README.md

@@ -0,0 +1,5 @@
+# Vue 3 + TypeScript + Vite
+
+This template should help get you started developing with Vue 3 and TypeScript 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.
+
+Learn more about the recommended Project Setup and IDE Support in the [Vue Docs TypeScript Guide](https://vuejs.org/guide/typescript/overview.html#project-setup).

+ 7 - 99
frontend/index.html

@@ -1,105 +1,13 @@
-<!DOCTYPE html>
-<html lang="zh-CN">
+<!doctype html>
+<html lang="en">
   <head>
-    <meta charset="utf-8">
-    <meta http-equiv="X-UA-Compatible" content="IE=edge">
-    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, maximum-scale=1.0, minimum-scale=1.0" />
-    <title></title>
-    <!-- 优化:vue渲染未完成之前,先加一个css动画 -->
-    <style>
-      #loadingPage {
-        background-color: #dedede;
-        font-size: 12px;
-      }
-      .base {
-        height: 9em;
-        left: 50%;
-        margin: -7.5em;
-        padding: 3em;
-        position: absolute;
-        top: 50%;
-        width: 9em;
-        transform: rotateX(45deg) rotateZ(45deg);
-        transform-style: preserve-3d;
-      }
-      .cube,
-      .cube:after,
-      .cube:before {
-        content: '';
-        float: left;
-        height: 3em;
-        position: absolute;
-        width: 3em;
-      }
-      /* Top */
-      .cube {
-        background-color: #06cf68;
-        position: relative;
-        transform: translateZ(3em);
-        transform-style: preserve-3d;
-        transition: .25s;
-        box-shadow: 13em 13em 1.5em rgba(0, 0, 0, 0.1);
-        animation: anim 1s infinite;
-      }
-      .cube:after {
-        background-color: #05a151;
-        transform: rotateX(-90deg) translateY(3em);
-        transform-origin: 100% 100%;
-      }
-      .cube:before {
-        background-color: #026934;
-        transform: rotateY(90deg) translateX(3em);
-        transform-origin: 100% 0;
-      }
-      .cube:nth-child(1) {
-        animation-delay: 0.05s;
-      }
-      .cube:nth-child(2) {
-        animation-delay: 0.1s;
-      }
-      .cube:nth-child(3) {
-        animation-delay: 0.15s;
-      }
-      .cube:nth-child(4) {
-        animation-delay: 0.2s;
-      }
-      .cube:nth-child(5) {
-        animation-delay: 0.25s;
-      }
-      .cube:nth-child(6) {
-        animation-delay: 0.3s;
-      }
-      .cube:nth-child(7) {
-        animation-delay: 0.35s;
-      }
-      .cube:nth-child(8) {
-        animation-delay: 0.4s;
-      }
-      .cube:nth-child(9) {
-        animation-delay: 0.45s;
-      }
-      @keyframes anim {
-        50% {
-          transform: translateZ(0.5em);
-        }
-      }
-    </style>
+    <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>Vite + Vue + TS</title>
   </head>
   <body>
-    <div id="loadingPage">
-      <div class='base'>
-        <div class='cube'></div>
-        <div class='cube'></div>
-        <div class='cube'></div>
-        <div class='cube'></div>
-        <div class='cube'></div>
-        <div class='cube'></div>
-        <div class='cube'></div>
-        <div class='cube'></div>
-        <div class='cube'></div>
-      </div>
-    </div>
     <div id="app"></div>
-    <script type="module" src="/src/main.js"></script>
+    <script type="module" src="/src/main.ts"></script>
   </body>
 </html>

+ 19 - 14
frontend/package.json

@@ -1,23 +1,28 @@
 {
-  "name": "ee",
-  "version": "1.0.0",
+  "name": "hlm_camera",
+  "private": true,
+  "version": "0.0.0",
+  "type": "module",
   "scripts": {
-    "dev": "vite --host --port 8080",
-    "serve": "vite --host --port 8080",
-    "build-staging": "vite build --mode staging",
-    "build": "vite build",
+    "dev": "vite",
+    "build": "vue-tsc -b && vite build",
     "preview": "vite preview"
   },
   "dependencies": {
-    "vue": "^3.2.33",
-    "vue-router": "^4.0.14"
+    "@types/axios": "0.14.4",
+    "axios": "1.7.9",
+    "pinia": "3.0.1",
+    "pinia-plugin-persistedstate": "4.2.0",
+    "element-plus": "2.1.7",
+    "vue": "3.5.13",
+    "vue-router": "4.5.0"
   },
   "devDependencies": {
-    "@vitejs/plugin-vue": "^4.2.3",
-    "@vue/compiler-sfc": "^3.2.33",
-    "less": "^4.1.2",
-    "less-loader": "^10.2.0",
-    "terser": "^5.19.1",
-    "vite": "^4.4.4"
+    "@types/node": "22.13.5",
+    "@vitejs/plugin-vue": "5.2.1",
+    "@vue/tsconfig": "0.7.0",
+    "typescript": "5.7.2",
+    "vite": "6.2.0",
+    "vue-tsc": "2.2.4"
   }
 }

+ 1 - 0
frontend/public/vite.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="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>

+ 18 - 8
frontend/src/App.vue

@@ -1,13 +1,23 @@
+<script setup lang="ts">
+</script>
+
 <template>
-  <router-view/>
+  <router-view
+  >
+  </router-view>
 </template>
 
-<script>
-export default {
-name: 'App',
-setup() {
-  document.getElementById('loadingPage').remove()
+<style scoped>
+.logo {
+  height: 6em;
+  padding: 1.5em;
+  will-change: filter;
+  transition: filter 300ms;
 }
+.logo:hover {
+  filter: drop-shadow(0 0 2em #646cffaa);
 }
-</script>
-<style lang="less"></style>
+.logo.vue:hover {
+  filter: drop-shadow(0 0 2em #42b883aa);
+}
+</style>

+ 0 - 13
frontend/src/api/main.js

@@ -1,13 +0,0 @@
-
-/**
- * 主进程与渲染进程通信频道定义
- * Definition of communication channels between main process and rendering process
- */
-const ipcApiRoute = {
-  test: 'controller.example.test',
-}
-
-export {
-  ipcApiRoute
-}
-

+ 4 - 0
frontend/src/apis/types/user.d.ts

@@ -0,0 +1,4 @@
+export interface UserRequest {
+    username: string;
+    password: string;
+}

+ 11 - 0
frontend/src/apis/user.ts

@@ -0,0 +1,11 @@
+import { GET,POST } from "@/utils/http";
+import type { UserRequest } from "@/apis/types/user";
+
+export async function getUserInfo(data:UserRequest){
+    return GET('/api/auth/user',data)
+
+}
+export async function login(data:UserRequest){
+    return POST('/api/auth/login',data)
+
+}

+ 0 - 8
frontend/src/assets/global.less

@@ -1,8 +0,0 @@
-#app {
-  font-family: Avenir, Helvetica, Arial, sans-serif;
-  -webkit-font-smoothing: antialiased;
-  -moz-osx-font-smoothing: grayscale;
-  text-align: center;
-  color: #2c3e50;
-  height: 100%;
-}

BIN
frontend/src/assets/logo.png


+ 1 - 0
frontend/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>

+ 60 - 0
frontend/src/components/HelloWorld.vue

@@ -0,0 +1,60 @@
+<script setup lang="ts">
+import { ref,onMounted } from 'vue'
+import { getUserInfo } from '@/apis/user'
+
+
+defineProps<{ msg: string }>()
+
+const count = ref(0)
+
+
+
+async function getUser() {
+  const res = await getUserInfo({
+    username: 'admin',
+    password: '123456'
+  }).catch(err=>{
+    console.log(err)
+  })
+  console.log(res)
+}
+
+onMounted(()=>{
+  getUser()
+})
+
+</script>
+
+<template>
+  <h1>{{ msg }}</h1>
+
+  <div class="card">
+    <button type="button" @click="count++">count is {{ count }}</button>
+    <p>
+      Edit
+      <code>components/HelloWorld.vue</code> to test HMR
+    </p>
+  </div>
+
+  <p>
+    Check out
+    <a href="https://vuejs.org/guide/quick-start.html#local" target="_blank"
+      >create-vue</a
+    >, the official Vue + Vite starter
+  </p>
+  <p>
+    Learn more about IDE Support for Vue in the
+    <a
+      href="https://vuejs.org/guide/scaling-up/tooling.html#ide-support"
+      target="_blank"
+      >Vue Docs Scaling up Guide</a
+    >.
+  </p>
+  <p class="read-the-docs">Click on the Vite and Vue logos to learn more</p>
+</template>
+
+<style scoped>
+.read-the-docs {
+  color: #888;
+}
+</style>

+ 0 - 10
frontend/src/components/global/index.js

@@ -1,10 +0,0 @@
-const modules = import.meta.globEager('./*.vue')
-const map = {}
-Object.keys(modules).forEach(file => {
-  const modulesName = file.replace('./', '').replace('.vue', '')
-  map[modulesName] = modules[file].default
-})
-const globalComponents = {
-  ...map,
-}
-export default globalComponents

+ 0 - 15
frontend/src/main.js

@@ -1,15 +0,0 @@
-import { createApp } from 'vue';
-import App from './App.vue';
-import './assets/global.less';
-import components from './components/global';
-import Router from './router/index';
-
-const app = createApp(App)
-app.config.productionTip = false
-
-// components
-for (const i in components) {
-  app.component(i, components[i])
-}
-
-app.use(Router).mount('#app')

+ 13 - 0
frontend/src/main.ts

@@ -0,0 +1,13 @@
+import { createApp } from 'vue'
+import pinia from "./stores/index";
+import router from "./router";
+import './style.css'
+import App from './App.vue'
+import ElementPlus from 'element-plus'
+import 'element-plus/dist/index.css'
+
+const app = createApp(App)
+app.use(ElementPlus)
+app.use(pinia)
+app.use(router)
+app.mount('#app')

+ 0 - 9
frontend/src/router/index.js

@@ -1,9 +0,0 @@
-import { createRouter, createWebHashHistory } from 'vue-router'
-import routerMap from './routerMap'
-
-const Router = createRouter({
-  history: createWebHashHistory(),
-  routes: routerMap,
-})
-
-export default Router

+ 25 - 0
frontend/src/router/index.ts

@@ -0,0 +1,25 @@
+import { createRouter, createWebHistory, RouteRecordRaw } from "vue-router";
+
+
+const routes: RouteRecordRaw[] = [
+    {
+        path: "/",
+        redirect: "/home"
+    },
+    {
+        path: "/home",
+        name: "home",
+        component: () => import("@/views/Home/index.vue"),
+    }
+];
+
+
+
+
+const router = createRouter({
+    history: createWebHistory(),
+    routes
+});
+
+
+export default router;

+ 0 - 21
frontend/src/router/routerMap.js

@@ -1,21 +0,0 @@
-/**
- * 基础路由
- * @type { *[] }
- */
-
-const constantRouterMap = [
-  {
-    path: '/',
-    name: 'Example',
-    redirect: { name: 'ExampleHelloIndex' },
-    children: [
-      {
-        path: '/example',
-        name: 'ExampleHelloIndex',
-        component: () => import('@/views/example/hello/Index.vue')
-      },
-    ]
-  },
-]
-
-export default constantRouterMap

+ 10 - 0
frontend/src/stores/index.ts

@@ -0,0 +1,10 @@
+// src/stores/index.ts
+import { createPinia } from 'pinia';
+import piniaPluginPersistedstate from 'pinia-plugin-persistedstate';
+
+const pinia = createPinia();
+
+// 使用持久化插件
+pinia.use(piniaPluginPersistedstate);
+
+export default pinia;

+ 31 - 0
frontend/src/stores/modules/user.ts

@@ -0,0 +1,31 @@
+// src/stores/index.ts
+import { defineStore } from 'pinia';
+
+
+const useUserInfo = defineStore('userInfo', {
+    state: () => ({
+        userInfo: {
+            account_name: 'John Doe',
+            phone:"18679381234"
+        },
+    }),
+    actions: {
+        // 添加必要的 actions
+        updateUserInfo(data: any ) {
+            this.userInfo = data;
+        }
+    },
+    getters: {
+        // 添加必要的 getters
+        getFullName(state): string {
+            return `${state.name}`;
+        }
+    },
+    persist: {
+        key: 'user-info',
+        storage: localStorage,
+        paths: ['userInfo',]
+    }
+});
+
+export default useUserInfo;

+ 79 - 0
frontend/src/style.css

@@ -0,0 +1,79 @@
+:root {
+  font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
+  line-height: 1.5;
+  font-weight: 400;
+
+  color-scheme: light dark;
+  color: rgba(255, 255, 255, 0.87);
+  background-color: #242424;
+
+  font-synthesis: none;
+  text-rendering: optimizeLegibility;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+a {
+  font-weight: 500;
+  color: #646cff;
+  text-decoration: inherit;
+}
+a:hover {
+  color: #535bf2;
+}
+
+body {
+  margin: 0;
+  display: flex;
+  place-items: center;
+  min-width: 320px;
+  min-height: 100vh;
+}
+
+h1 {
+  font-size: 3.2em;
+  line-height: 1.1;
+}
+
+button {
+  border-radius: 8px;
+  border: 1px solid transparent;
+  padding: 0.6em 1.2em;
+  font-size: 1em;
+  font-weight: 500;
+  font-family: inherit;
+  background-color: #1a1a1a;
+  cursor: pointer;
+  transition: border-color 0.25s;
+}
+button:hover {
+  border-color: #646cff;
+}
+button:focus,
+button:focus-visible {
+  outline: 4px auto -webkit-focus-ring-color;
+}
+
+.card {
+  padding: 2em;
+}
+
+#app {
+  max-width: 1280px;
+  margin: 0 auto;
+  padding: 2rem;
+  text-align: center;
+}
+
+@media (prefers-color-scheme: light) {
+  :root {
+    color: #213547;
+    background-color: #ffffff;
+  }
+  a:hover {
+    color: #747bff;
+  }
+  button {
+    background-color: #f9f9f9;
+  }
+}

+ 185 - 0
frontend/src/utils/http.ts

@@ -0,0 +1,185 @@
+import axios, { AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios';
+import { ElMessage as Message, ElMessageBox as MessageBox, ElLoading as Loading } from 'element-plus';
+
+// 加载动画的并发管理
+const activeRequests = new Set<string>();
+let loadingObj = null;
+/**
+ * 关闭加载动画
+ * 当所有请求完成时,关闭加载动画
+ */
+function loadingClose(requestId: string) {
+    activeRequests.delete(requestId);
+    if (activeRequests.size === 0 && loadingObj) {
+        loadingObj.close();
+        loadingObj = null
+    }
+}
+
+/**
+ * 创建一个axios实例,用于发送HTTP请求
+ * 配置了请求拦截器和响应拦截器,支持加载动画和错误提示
+ */
+const service = axios.create({
+    timeout: 5000, // 设置请求超时时间
+});
+
+// 请求拦截器
+service.interceptors.request.use(
+    (config: AxiosRequestConfig) => {
+        // 在发送请求之前做些什么,例如添加 token
+        const token = localStorage.getItem('token');
+        if (token) {
+            config.headers['Authorization'] = `Bearer ${token}`;
+        }
+
+        // 如果配置中启用了加载动画,则显示加载动画
+        if (config.loading) {
+            const requestId = `${Date.now()}-${Math.random()}`;
+            activeRequests.add(requestId);
+            if (activeRequests.size === 1) {
+                loadingObj = Loading.service({
+                    lock: true,
+                    text: '请稍候',
+                    background: 'rgba(0, 0, 0, 0)',
+                });
+            }
+            config.requestId = requestId; // 将 requestId 挂载到 config 上
+        }
+
+        return config;
+    },
+    (error: AxiosError) => {
+        // 对请求错误做些什么
+        return Promise.reject(error);
+    }
+);
+
+// 响应拦截器
+service.interceptors.response.use(
+    (response: AxiosResponse) => {
+        // 对响应数据做点什么
+        const res = response.data;
+
+        // 如果配置中启用了加载动画,则关闭加载动画
+        if (response.config?.loading && response.config.requestId) {
+            loadingClose(response.config.requestId as string);
+        }
+
+        // 如果自定义状态码不为0,则判断为错误
+        if (res.code !== 0) {
+            switch (res.code) {
+                default:
+                    if (response.config.showErrorMessage) {
+                        if (res.message?.length > 30 || res.code === 400011) {
+                            let message = '<div style="white-space: pre-line; max-height: 500px; overflow: auto;">' + res.message + '</div>' || 'Error';
+                            MessageBox.alert(message, '提示', {
+                                dangerouslyUseHTMLString: true,
+                            });
+                        } else {
+                            Message({
+                                message: res.message || 'Error',
+                                type: 'error',
+                                duration: 5 * 1000,
+                            });
+                        }
+                    }
+                    break;
+            }
+
+            return Promise.reject(res || 'Error');
+        } else {
+            return res;
+        }
+    },
+    (error: AxiosError) => {
+        // 对响应错误做点什么
+        let errMessage = '';
+
+        // 如果配置中启用了加载动画,则关闭加载动画
+        if (error.config?.loading && error.config.requestId) {
+            loadingClose(error.config.requestId as string);
+        }
+
+        try {
+            if (error.response) {
+                switch (error.response.status) {
+                    case 400: errMessage = '请求错误(400)'; break;
+                    case 401: errMessage = '登录失效'; break;
+                    case 403: errMessage = '拒绝访问(403)'; break;
+                    case 404: errMessage = '请求出错(404)'; break;
+                    case 408: errMessage = '请求超时(408)'; break;
+                    case 500: errMessage = '服务器错误(500)'; break;
+                    case 501: errMessage = '服务未实现(501)'; break;
+                    case 502: errMessage = '网络错误(502)'; break;
+                    case 503: errMessage = '服务不可用(503)'; break;
+                    case 504: errMessage = '网络超时(504)'; break;
+                    case 505: errMessage = 'HTTP版本不受支持(505)'; break;
+                    default: errMessage = '连接出错!';
+                }
+            } else {
+                errMessage = '未知错误';
+            }
+        } catch (e) {
+            console.log(e);
+        }
+
+        // 如果配置中启用了错误提示,则显示错误信息
+        if (error.config?.showErrorMessage) {
+            if (error.message && error.message.includes('timeout')) {
+                Message({
+                    message: '请求超时!',
+                    type: 'error',
+                    duration: 5 * 1000,
+                });
+            } else if (errMessage) {
+                Message({
+                    message: errMessage,
+                    type: 'error',
+                    duration: 5 * 1000,
+                });
+            }
+        }
+
+        // 对响应错误做处理
+        return Promise.reject(error);
+    }
+);
+
+
+/**
+ * 发起 GET 请求
+ *
+ * @template T 泛型,表示返回数据的类型
+ * @param {string} url 请求的 URL
+ * @param {any} [params] 请求参数
+ * @returns {Promise<T>} 返回一个 Promise,解析为响应数据
+ */
+export function GET<T>(url: string, params?: any): Promise<T> {
+    return service.get(url, {
+        params: params,
+        loading: params?.loading ?? false,
+        showErrorMessage: params?.showErrorMessage ?? true,
+    });
+}
+
+/**
+ * 发起 POST 请求
+ *
+ * @template T 泛型,表示返回数据的类型
+ * @param {string} url 请求的 URL
+ * @param {any} [data] 请求体
+ * @param {any} [config] 请求配置
+ * @returns {Promise<T>} 返回一个 Promise,解析为响应数据
+ */
+export function POST<T>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T> {
+    return service.post(url, data, {
+        ...config,
+        loading: config?.loading ?? true,
+        showErrorMessage: config?.showErrorMessage ?? true,
+    });
+}
+
+
+// 导出配置好的 axios 实例
+export default service;

+ 0 - 33
frontend/src/utils/ipcRenderer.js

@@ -1,33 +0,0 @@
-const Renderer = (window.require && window.require('electron')) || window.electron || {};
-
-/**
- * ipc
- * 官方api说明:https://www.electronjs.org/zh/docs/latest/api/ipc-renderer
- * 
- * 属性/方法
- * ipc.invoke(channel, param) - 发送异步消息(invoke/handle 模型)
- * ipc.sendSync(channel, param) - 发送同步消息(send/on 模型)
- * ipc.on(channel, listener) - 监听 channel, 当新消息到达,调用 listener
- * ipc.once(channel, listener) - 添加一次性 listener 函数
- * ipc.removeListener(channel, listener) - 为特定的 channel 从监听队列中删除特定的 listener 监听者
- * ipc.removeAllListeners(channel) - 移除所有的监听器,当指定 channel 时只移除与其相关的所有监听器
- * ipc.send(channel, ...args) - 通过channel向主进程发送异步消息
- * ipc.postMessage(channel, message, [transfer]) - 发送消息到主进程
- * ipc.sendTo(webContentsId, channel, ...args) - 通过 channel 发送消息到带有 webContentsId 的窗口
- * ipc.sendToHost(channel, ...args) - 消息会被发送到 host 页面上的 <webview> 元素
- */
-
-/**
- * ipc
- */
-const ipc = Renderer.ipcRenderer || undefined;
-
-/**
- * 是否为EE环境
- */
-const isEE = ipc ? true : false;
-
-export {
-  Renderer, ipc, isEE
-};
-

+ 58 - 0
frontend/src/views/Home/index.vue

@@ -0,0 +1,58 @@
+<template>
+
+  <div>{{useUserInfoStore.userInfo.account_name}}</div>
+  <div>{{useUserInfoStore.userInfo.phone}}</div>
+
+
+
+  <div class="mb-4">
+    <el-button @click="loginError">登录失败</el-button>
+    <el-button type="primary"  @click="loginIn">登录成功</el-button>
+    <el-button type="success">Success</el-button>
+    <el-button type="info">Info</el-button>
+    <el-button type="warning">Warning</el-button>
+    <el-button type="danger">Danger</el-button>
+  </div>
+</template>
+
+<script setup lang="ts">
+import useUserInfo from "@/stores/modules/user";
+const useUserInfoStore = useUserInfo();
+import { login,getUserInfo } from '@/apis/user'
+
+
+async  function loginIn() {
+  console.log('aaa')
+  const res = await login({
+    "site":1,
+    "username":"13777879245",
+    "password":"753159",
+    "type":1,
+    "device":"aigc-photo"
+  })
+
+  const userRes = await getUserInfo({
+    "site":1,
+    "token":res.data.token
+  })
+
+  useUserInfoStore.updateUserInfo(userRes.data)
+
+
+
+}
+async function loginError() {
+  console.log('bbb')
+  const res = await login({
+    "site":1,
+    "username":"18679381902",
+    "password":"123456",
+    "device":"aigc-photo"
+  })
+  console.log(res)
+}
+</script>
+
+<style scoped>
+
+</style>

+ 0 - 76
frontend/src/views/example/hello/Index.vue

@@ -1,76 +0,0 @@
-<template>
-  <section id="hero">
-    <h1 class="tagline">
-      <span class="accent">Electron-Egg</span>
-    </h1>
-    <p class="description">
-      A fast, desktop software development framework
-    </p>
-    <p class="actions">
-      <a class="setup" href="https://www.kaka996.com/" target="_blank">Get Started</a>
-    </p>
-  </section>
-</template>
-<script>
-
-export default {
-  data() {
-    return {};
-  },
-};
-</script>
-<style scoped>
-section {
-  padding: 42px 32px;
-}
-
-#hero {
-  padding: 150px 32px;
-  text-align: center;
-  height: 100%;
-}
-
-.tagline {
-  font-size: 52px;
-  line-height: 1.25;
-  font-weight: bold;
-  letter-spacing: -1.5px;
-  max-width: 960px;
-  margin: 0px auto;
-}
-html:not(.dark) .accent,
-.dark .tagline {
-  background: -webkit-linear-gradient(315deg, #42d392 25%, #647eff);
-  background-clip: text;
-  -webkit-background-clip: text;
-  -webkit-text-fill-color: transparent;
-}
-
-.description {
-  max-width: 960px;
-  line-height: 1.5;
-  color: var(--vt-c-text-2);
-  transition: color 0.5s;
-  font-size: 22px;
-  margin: 24px auto 40px;
-}
-.actions a {
-  font-size: 16px;
-  display: inline-block;
-  background-color: var(--vt-c-bg-mute);
-  padding: 8px 18px;
-  font-weight: 500;
-  border-radius: 8px;
-  transition: background-color 0.5s, color 0.5s;
-  text-decoration:none;
-}
-.actions .setup {
-  color: var(--vt-c-text-code);
-  background: -webkit-linear-gradient(315deg, #42d392 25%, #647eff);
-}
-.actions .setup:hover {
-  background-color: var(--vt-c-gray-light-4);
-  transition-duration: 0.2s;
-}
-</style>
-  

+ 1 - 0
frontend/src/vite-env.d.ts

@@ -0,0 +1 @@
+/// <reference types="vite/client" />

+ 14 - 0
frontend/tsconfig.app.json

@@ -0,0 +1,14 @@
+{
+  "extends": "@vue/tsconfig/tsconfig.dom.json",
+  "compilerOptions": {
+    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+    /* Linting */
+    "strict": true,
+    "noUnusedLocals": true,
+    "noUnusedParameters": true,
+    "noFallthroughCasesInSwitch": true,
+    "noUncheckedSideEffectImports": true
+  },
+  "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"]
+}

+ 52 - 0
frontend/tsconfig.json

@@ -0,0 +1,52 @@
+{
+  // 定义项目中包含的文件列表
+  "files": [],
+  // 定义项目中引用的其他配置文件
+  "references": [
+    { "path": "./tsconfig.app.json" },
+    { "path": "./tsconfig.node.json" }
+  ],
+  // 设置编译器选项
+  "compilerOptions": {
+    // 定义类型根目录,用于指定在哪里查找类型定义文件
+    "typeRoots": ["./node_modules/@types", "./src/types"],
+    // 设置JavaScript代码生成的目标版本
+    "target": "ES2020",
+    // 使用定义字段时生成定义属性
+    "useDefineForClassFields": true,
+    // 设置模块系统的类型
+    "module": "ESNext",
+    // 指定要包含的库
+    "lib": ["ES2020","DOM","DOM.Iterable"],
+    // 跳过对库的类型检查
+    "skipLibCheck": true,
+    // 设置模块解析策略
+    "moduleResolution": "bundler",
+    // 允许从具有默认导出的模块中进行默认导入
+    "allowSyntheticDefaultImports": true,
+    // 允许导入JSON模块
+    "resolveJsonModule": true,
+    // 将每个文件作为独立的模块对待
+    "isolatedModules": true,
+    // 不生成任何输出文件
+    "noEmit": true,
+    // 保留JSX语法
+    "jsx": "preserve",
+    // 启用严格类型检查
+    "strict": false,
+    // 警告未使用的局部变量
+    "noUnusedLocals": true,
+    // 警告未使用的参数
+    "noUnusedParameters": true,
+    // 在switch语句中禁止fallthrough行为
+    "noFallthroughCasesInSwitch": true,
+    // 设置基础目录
+    "baseUrl": ".",
+    // 设置路径映射
+    "paths": {
+      "@/*": ["./src/*"]
+    }
+  },
+  // 指定要包含在编译中的文件
+  "include": ["./src/**/*.ts", "./src/**/*.d.ts", "./src/**/*.tsx", "./src/**/*.vue"]
+}

+ 24 - 0
frontend/tsconfig.node.json

@@ -0,0 +1,24 @@
+{
+  "compilerOptions": {
+    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+    "target": "ES2022",
+    "lib": ["ES2023"],
+    "module": "ESNext",
+    "skipLibCheck": true,
+
+    /* Bundler mode */
+    "moduleResolution": "bundler",
+    "allowImportingTsExtensions": true,
+    "isolatedModules": true,
+    "moduleDetection": "force",
+    "noEmit": true,
+
+    /* Linting */
+    "strict": true,
+    "noUnusedLocals": true,
+    "noUnusedParameters": true,
+    "noFallthroughCasesInSwitch": true,
+    "noUncheckedSideEffectImports": true
+  },
+  "include": ["vite.config.ts"]
+}

+ 0 - 49
frontend/vite.config.js

@@ -1,49 +0,0 @@
-import vue from '@vitejs/plugin-vue'
-import { defineConfig } from 'vite'
-
-import path from 'path'
-// https://vitejs.dev/config/
-export default defineConfig(({ command, mode }) => {
-  return {
-    // 项目插件
-    plugins: [
-      vue(),
-    ],
-    // 基础配置
-    base: './',
-    publicDir: 'public',
-    resolve: {
-      alias: {
-        '@': path.resolve(__dirname, 'src'),
-      },
-    },
-    css: {
-      preprocessorOptions: {
-        less: {
-          modifyVars: {
-            '@border-color-base': '#dce3e8',
-          },
-          javascriptEnabled: true,
-        },
-      },
-    },
-    build: {
-      outDir: 'dist',
-      assetsDir: 'assets',
-      assetsInlineLimit: 4096,
-      cssCodeSplit: true,
-      brotliSize: false,
-      sourcemap: false,
-      minify: 'terser',
-      terserOptions: {
-        compress: {
-          // 生产环境去除console及debug
-          drop_console: false,
-          drop_debugger: true,
-        },
-      },
-    },
-  }
-})
-
-

+ 36 - 0
frontend/vite.config.ts

@@ -0,0 +1,36 @@
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+import path from 'path'
+
+// https://vite.dev/config/
+export default defineConfig({
+  // 插件配置,这里使用了Vue插件,以便支持Vue项目的构建
+  plugins: [vue()],
+
+  // 解析配置,用于配置模块查找和解析行为
+  resolve: {
+    // 定义解析文件的扩展名,这允许导入这些文件时省略扩展名
+    extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue'],
+
+    // 路径别名配置,这里定义了'@'符号指向项目的src目录
+    // 这有助于减少路径引用的复杂性,提高代码的可读性和可维护性
+    alias: {
+      '@': path.resolve(__dirname, './src'),
+    },
+  },
+  // 配置服务器相关设置
+  server: {
+    // 设置服务器监听的端口
+    port: 3000,
+    // 配置代理设置,用于开发环境中代理API请求
+    proxy: {
+      // 当请求以'/api'开头时,将其代理到目标服务器
+      '/api': {
+        // 目标服务器的地址
+        target: 'http://dev2.pubdata.cn',
+        // 允许更改目标服务器的来源
+        changeOrigin: true
+      },
+    },
+  },
+})