Kaynağa Gözat

基本完全优化到能给学生的状态

chillqi 2 yıl önce
ebeveyn
işleme
2f83420dbd

+ 0 - 1
.gitignore

@@ -3,7 +3,6 @@ logs
 *.log
 npm-debug.log*
 yarn-debug.log*
-yarn-error.log*
 pnpm-debug.log*
 lerna-debug.log*
 

+ 0 - 18
README.md

@@ -1,18 +0,0 @@
-# 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.
-
-## 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).
-
-## Type Support For `.vue` Imports in TS
-
-TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
-
-If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
-
-1. Disable the built-in TypeScript Extension
-   1. Run `Extensions: Show Built-in Extensions` from VSCode's command palette
-   2. Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
-2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.

+ 3 - 0
components.d.ts

@@ -21,7 +21,10 @@ declare module 'vue' {
     ElIcon: typeof import('element-plus/es')['ElIcon']
     ElInput: typeof import('element-plus/es')['ElInput']
     ElMain: typeof import('element-plus/es')['ElMain']
+    ElOption: typeof import('element-plus/es')['ElOption']
+    ElResult: typeof import('element-plus/es')['ElResult']
     ElRow: typeof import('element-plus/es')['ElRow']
+    ElSelect: typeof import('element-plus/es')['ElSelect']
     ElTag: typeof import('element-plus/es')['ElTag']
     Header: typeof import('./src/components/Header.vue')['default']
     RouterLink: typeof import('vue-router')['RouterLink']

+ 1 - 1
src/api/_prefix.ts

@@ -2,4 +2,4 @@
 export const API_MODULE = '/api'
 
 //用户模块
-export const USER_MODULE= `${API_MODULE}/users`
+export const USER_MODULE = `${API_MODULE}/users`

+ 6 - 6
src/api/user.ts

@@ -12,18 +12,18 @@ type RegisterInfo = {
     phone: string,
     password: string,
     address: string,
-    createTime: string
 }
 
 type UpdateInfo = {
-    name: string,
-    password: string,
-    address: string,
+    name: string | null,
+    password: string | null,
+    address: string | null,
 }
 
+// 如果有“Vue: This may be converted to an async function”警告,可以不管
 // 用户登录
 export const userLogin = (loginInfo: LoginInfo) => {
-    return axios.post(`${USER_MODULE}/login`,null, {params: loginInfo})
+    return axios.post(`${USER_MODULE}/login`, null, {params: loginInfo})
         .then(res => {
             return res
         })
@@ -32,7 +32,7 @@ export const userLogin = (loginInfo: LoginInfo) => {
 // 用户注册
 export const userRegister = (registerInfo: RegisterInfo) => {
     return axios.post(`${USER_MODULE}/register`, registerInfo,
-                    {headers: {'Content-Type': 'application/json'}})
+        {headers: {'Content-Type': 'application/json'}})
         .then(res => {
             return res
         })

+ 2 - 2
src/components/Header.vue

@@ -29,7 +29,7 @@ function logout() {
 
 <template>
   <el-header class="custom-header" height="20">
-    <el-row :gutter="10" :justify="'space-around'">
+    <el-row :gutter="10">
 
       <el-col :span="3" class="header-icon">
         <router-link to="/dashboard" v-slot="{navigate}" class="no-link">
@@ -41,7 +41,7 @@ function logout() {
         <el-tag class="role-tag" size="large">{{ parseRole(role) }}版</el-tag>
       </el-col>
 
-      <el-col :span="8">
+      <el-col :span="16">
       </el-col>
 
       <el-col :span="1" class="header-icon">

+ 6 - 1
src/main.ts

@@ -1,3 +1,7 @@
+// createApp是Vue3的一个函数,用于创建一个新的Vue应用实例。
+// 这个函数接收一个根组件作为参数,并返回一个可以链式调用的应用实例。
+// App是从./App.vue文件中导入的默认导出。在Vue中,.vue文件通常代表一个单文件组件。
+// 所以,App是你的应用的根组件。
 import { createApp } from 'vue'
 import {router} from './router'
 import App from './App.vue'
@@ -6,8 +10,9 @@ import ElementPlus from 'element-plus'
 import 'element-plus/dist/index.css'
 import './style.css'
 
-
+//设置后端地址(本地或服务器),会将请求转发到后端端口
 axios.defaults.baseURL = ("http://localhost:8080")
 axios.defaults.timeout = 30000;
 
+//创建一个新的Vue应用实例,使用ElementPlus插件和路由,然后挂载到页面上id为'app'的元素上。
 createApp(App).use(ElementPlus).use(router).mount('#app')

+ 17 - 18
src/router/index.ts

@@ -1,19 +1,18 @@
-import {createRouter, createWebHistory} from "vue-router";
+import {createRouter, createWebHashHistory} from "vue-router"
 
 const router = createRouter({
-    history: createWebHistory(),
+    history: createWebHashHistory(),
     routes: [{
         path: '/',
         redirect: '/login',
     }, {
         path: '/login',
         component: () => import('../views/user/Login.vue'),
-        meta: {
-            title: '登录'
-        }
+        meta: {title: '用户登录'}
     }, {
         path: '/register',
         component: () => import('../views/user/Register.vue'),
+        meta: {title: '用户注册'}
     }, {
         path: '/home',
         redirect: '/dashboard',
@@ -23,18 +22,14 @@ const router = createRouter({
                 path: '/dashboard',
                 name: 'Dashboard',
                 component: () => import('../views/user/Dashboard.vue'),
-                meta: {
-                    title: '个人信息'
-                }
+                meta: {title: '个人信息'}
             },
         ]
     }, {
         path: '/404',
         name: '404',
         component: () => import('../views/NotFound.vue'),
-        meta: {
-            title: '404'
-        }
+        meta: {title: '404'}
     }, {
         path: '/:catchAll(.*)',
         redirect: '/404'
@@ -46,12 +41,16 @@ router.beforeEach((to, _, next) => {
     const token: string | null = sessionStorage.getItem('token');
     const role: string | null = sessionStorage.getItem('role')
 
+    if (to.meta.title) {
+        document.title = to.meta.title
+    }
+
     if (token) {
         if (to.meta.permission) {
             if (to.meta.permission.includes(role!)) {
-                next();
+                next()
             } else {
-                next('/404');
+                next('/404')
             }
         } else {
             next()
@@ -59,13 +58,13 @@ router.beforeEach((to, _, next) => {
     } else {
         if (to.path === '/login') {
             next();
+            return
         } else if (to.path === '/register') {
-            next();
+            next()
         } else {
-            next('/login');
+            next('/login')
         }
     }
-});
-
+})
 
-export {router};
+export {router}

+ 3 - 1
src/shim-vue.d.ts

@@ -1,5 +1,7 @@
+// 一个TypeScript声明文件,用于告诉TypeScript编译器如何处理`.vue`文件。这是Vue3和TypeScript集成的一部分。
+
 declare module '*.vue' {
     import { defineComponent } from 'vue'
     constcomponent: ReturnType<typeof defineComponent>
     export default component
-}
+}

+ 2 - 0
src/style.css

@@ -1,3 +1,5 @@
+/*一些公用的css*/
+
 :root {
     font-family: sans-serif;
     line-height: 1.5;

+ 10 - 1
src/utils/index.ts

@@ -1,5 +1,5 @@
 //将身份转化为中文显示
-export function parseRole(role: string) {
+export function parseRole(role: string | null) {
     if (role === 'MANAGER') {
         return "管理员"
     } else if (role === 'CUSTOMER') {
@@ -10,3 +10,12 @@ export function parseRole(role: string) {
         return "CEO"
     }
 }
+
+//将时间转化为日常方式
+export function parseTime(time: string) {
+    let times = time.split(/T|\./)
+    return times[0] + " " + times[1]
+}
+
+
+

+ 11 - 9
src/utils/request.ts

@@ -1,13 +1,14 @@
-import axios from 'axios';
+import axios from 'axios'
 
-const service = axios.create({
-    baseURL: 'http://localhost:8080'
-});
+//创建一个axios的实例service
+const service = axios.create()
 
+//判断是否登录
 function hasToken() {
     return !(sessionStorage.getItem('token') == '')
 }
 
+//当前实例的拦截器,对所有要发送给后端的请求进行处理,在其中加入token
 service.interceptors.request.use(
     config => {
         if(hasToken()) {
@@ -19,23 +20,24 @@ service.interceptors.request.use(
         console.log(error);
         return Promise.reject();
     }
-);
+)
 
+//当前实例的拦截器,对所有从后端收到的请求进行处理,检验http的状态码
 service.interceptors.response.use(
     response => {
         if (response.status === 200) {
-            return response.data;
+            return response;
         } else {
-            Promise.reject();
+            return Promise.reject();
         }
     },
     error => {
         console.log(error);
         return Promise.reject();
     }
-);
+)
 
-export default service;
+//设置为全局变量
 export {
     service as axios
 }

+ 21 - 35
src/views/user/Dashboard.vue

@@ -1,6 +1,7 @@
 <script setup lang="ts">
-import {ref, computed} from 'vue';
+import {ref, computed} from 'vue'
 import {userInfo, userInfoUpdate} from '../../api/user.ts'
+import {parseRole, parseTime} from "../../utils"
 import {router} from '../../router'
 import {UserFilled} from "@element-plus/icons-vue";
 
@@ -18,19 +19,21 @@ const displayInfoCard = ref(false)
 const password = ref('')
 const confirmPassword = ref('')
 
-const hasPasswordInput = computed(() => password.value != '');
-const hasConfirmPasswordInput = computed(() => confirmPassword.value != '');
-const isPasswordIdentical = computed(() => password.value == confirmPassword.value);
+const hasConfirmPasswordInput = computed(() => confirmPassword.value != '')
+const isPasswordIdentical = computed(() => password.value == confirmPassword.value)
+const changeDisabled = computed(() => {
+  return !(hasConfirmPasswordInput.value && isPasswordIdentical.value)
+})
 
 getUserInfo()
 
 function getUserInfo() {
   userInfo().then(res => {
-    name.value = res.result.name
-    tel.value = res.result.phone
-    storeName.value = res.result.storeName
-    address.value = res.result.address
-    regTime.value = parseTime(res.result.createTime)
+    name.value = res.data.result.name
+    tel.value = res.data.result.phone
+    storeName.value = res.data.result.storeName
+    address.value = res.data.result.address
+    regTime.value = parseTime(res.data.result.createTime)
 
     newName.value = name.value
   })
@@ -42,18 +45,18 @@ function updateInfo() {
     password: null,
     address: address.value,
   }).then(res => {
-    if (res.code === '000') {
+    if (res.data.code === '000') {
       ElMessage({
         customClass: 'customMessage',
         type: 'success',
         message: '更新成功!',
       })
       getUserInfo()
-    } else if (res.code === '400') {
+    } else if (res.data.code === '400') {
       ElMessage({
         customClass: 'customMessage',
         type: 'error',
-        message: '更新失败!',
+        message: res.data.msg,
       })
     }
   })
@@ -65,7 +68,7 @@ function updatePassword() {
     password: password.value,
     address: null
   }).then(res => {
-    if (res.code === '000') {
+    if (res.data.code === '000') {
       password.value = ''
       confirmPassword.value = ''
       ElMessageBox.alert(
@@ -78,36 +81,18 @@ function updatePassword() {
             showClose: false,
             roundButton: true,
             center: true
-
           }).then(() => router.push({path: "/login"}))
-    } else if (res.code === '400') {
+    } else if (res.data.code === '400') {
       ElMessage({
         customClass: 'customMessage',
         type: 'error',
-        message: '更新失败!',
+        message: res.data.msg,
       })
       password.value = ''
       confirmPassword.value = ''
     }
   })
 }
-
-function parseRole() {
-  if (role === 'MANAGER') {
-    return "管理员"
-  } else if (role === 'CUSTOMER') {
-    return "顾客"
-  } else if (role === 'STAFF') {
-    return "商家"
-  } else if (role === 'CEO') {
-    return "CEO"
-  }
-}
-
-function parseTime(time) {
-  let times = time.split(/T|\./)
-  return times[0] + " " + times[1]
-}
 </script>
 
 
@@ -136,7 +121,7 @@ function parseTime(time) {
         </template>
 
         <el-descriptions-item label="身份">
-          <el-tag>{{ parseRole() }}</el-tag>
+          <el-tag>{{ parseRole(role) }}</el-tag>
         </el-descriptions-item>
 
         <el-descriptions-item label="所属商店" v-if="role === 'STAFF'">
@@ -189,7 +174,8 @@ function parseTime(time) {
       <template #header>
         <div class="card-header">
           <span>修改密码</span>
-          <el-button @click="updatePassword" :disabled="!hasConfirmPasswordInput || !isPasswordIdentical">修改
+          <el-button @click="updatePassword" :disabled="changeDisabled">
+            修改
           </el-button>
         </div>
       </template>

+ 6 - 6
src/views/user/Login.vue

@@ -27,23 +27,23 @@ function handleLogin() {
     phone: tel.value,
     password: password.value
   }).then(res => {
-    if (res.code === '000') {
+    if (res.data.code === '000') {
       ElMessage({
         message: "登录成功!",
         type: 'success',
         center: true,
       })
-      const token = res.result
+      const token = res.data.result
       sessionStorage.setItem('token', token)
 
       userInfo().then(res => {
-        sessionStorage.setItem('name', res.result.name)
-        sessionStorage.setItem('role', res.result.role)
+        sessionStorage.setItem('name', res.data.result.name)
+        sessionStorage.setItem('role', res.data.result.role)
         router.push({path: "/dashboard"})
       })
-    } else if (res.code === '400') {
+    } else if (res.data.code === '400') {
       ElMessage({
-        message: res.msg,
+        message: res.data.msg,
         type: 'error',
         center: true,
       })

+ 3 - 4
src/views/user/Register.vue

@@ -40,18 +40,17 @@ function handleRegister() {
     phone: tel.value,
     password: password.value,
     address: address.value,
-    createTime: new Date().getTime()
   }).then(res => {
-    if (res.code === '000') {
+    if (res.data.code === '000') {  //类型守卫,它检查 res.data 对象中是否存在名为 code 的属性
       ElMessage({
         message: "注册成功!请登录账号",
         type: 'success',
         center: true,
       })
       router.push({path: "/login"})
-    } else if (res.code === '400') {
+    } else if (res.data.code === '400') {
       ElMessage({
-        message: res.msg,
+        message: res.data.msg,
         type: 'error',
         center: true,
       })

+ 3 - 4
vite.config.ts

@@ -16,10 +16,9 @@ export default defineConfig({
         Components({
             resolvers: [ElementPlusResolver()],
         })],
-    devServer: {
-        port: 3000,
+    server: {
+        port: 3000,   //设定前端运行的端口
         open: true,
-        hot: true,//自动保存
     },
-
+    base: './'
 })