Browse Source

feat: 前端调用后端

qinlaiqiao 4 years ago
parent
commit
4fef0a93ab

+ 1 - 0
.eslintignore

@@ -2,3 +2,4 @@
 /dist
 /public
 vue.config.js
+package-lock.json

+ 11 - 10
.eslintrc.js

@@ -16,20 +16,21 @@ module.exports = {
   },
   rules: {
     /* "import/extensions": [
-                    "error",
-                    "ignorePackages",
-                    {
-                      js: "never",
-                      mjs: "never",
-                      jsx: "never",
-                      ts: "never",
-                      tsx: "never",
-                    },
-                  ], */
+                        "error",
+                        "ignorePackages",
+                        {
+                          js: "never",
+                          mjs: "never",
+                          jsx: "never",
+                          ts: "never",
+                          tsx: "never",
+                        },
+                      ], */
     "import/no-unresolved": "off",
     "@typescript-eslint/no-empty-function": "off",
     "@typescript-eslint/no-explicit-any": "off",
     "@typescript-eslint/explicit-module-boundary-types": "off",
+    "vuejs-accessibility/form-control-has-label": "off",
     "@typescript-eslint/no-non-null-assertion": "off",
     "import/extensions": "off",
     "vuejs-accessibility/click-events-have-key-events": "off",

+ 14 - 4
package-lock.json

@@ -1366,6 +1366,16 @@
         "pkg-dir": "^5.0.0",
         "tslib": "^2.3.0",
         "upath": "^2.0.1"
+      },
+      "dependencies": {
+        "axios": {
+          "version": "0.21.4",
+          "resolved": "http://192.168.1.90:4873/axios/-/axios-0.21.4.tgz",
+          "integrity": "sha1-xnuQ3AVo5cHPKwuFjEO6KOLtpXU=",
+          "requires": {
+            "follow-redirects": "^1.14.0"
+          }
+        }
       }
     },
     "@midwayjs/hooks-testing-library": {
@@ -3652,11 +3662,11 @@
       "dev": true
     },
     "axios": {
-      "version": "0.21.4",
-      "resolved": "http://192.168.1.90:4873/axios/-/axios-0.21.4.tgz",
-      "integrity": "sha1-xnuQ3AVo5cHPKwuFjEO6KOLtpXU=",
+      "version": "0.24.0",
+      "resolved": "http://192.168.1.90:4873/axios/-/axios-0.24.0.tgz",
+      "integrity": "sha1-gE5voeS5xSiFAd2d/1anoJQNINY=",
       "requires": {
-        "follow-redirects": "^1.14.0"
+        "follow-redirects": "^1.14.4"
       }
     },
     "babel-jest": {

+ 2 - 0
package.json

@@ -13,6 +13,7 @@
   },
   "dependencies": {
     "@midwayjs/bootstrap": "^2.13.4",
+    "@midwayjs/decorator": "^2.13.2",
     "@midwayjs/hooks": "^2.2.2",
     "@midwayjs/koa": "^2.11.0",
     "@sc/handsontable": "^6.3.11",
@@ -21,6 +22,7 @@
     "animate.css": "^4.1.1",
     "animejs": "^3.2.1",
     "ant-design-vue": "2.2.7",
+    "axios": "^0.24.0",
     "echarts": "^5.2.2",
     "element-plus": "^1.1.0-beta.24",
     "koa-bodyparser": "^4.3.0",

+ 2 - 1
src/apis/configuration.ts

@@ -1,10 +1,11 @@
 import { hooks, createConfiguration } from "@midwayjs/hooks";
 import bodyParser from "koa-bodyparser";
+import error from "@/apis/middleware/error";
 
 export default createConfiguration({
   imports: [
     hooks({
-      middleware: [bodyParser()],
+      middleware: [error, bodyParser()],
     }),
   ],
 });

+ 0 - 18
src/apis/controller/index.ts

@@ -1,18 +0,0 @@
-import { useContext } from "@midwayjs/hooks";
-import { Context } from "@midwayjs/koa";
-
-function useKoaContext() {
-  return useContext<Context>();
-}
-
-export default async () => {
-  console.log("index方法被调用");
-  return {
-    message: "Hello World",
-    method: useKoaContext().method,
-  };
-};
-
-export const post = async (name: string) => {
-  return { method: "POST", name };
-};

src/apis/controller/index.test.ts → src/apis/controller/test/index.test.ts


+ 13 - 0
src/apis/controller/user.ts

@@ -0,0 +1,13 @@
+import { useUserService } from "@/apis/hooks/service";
+import Response from "@/utils/common/Response";
+
+export async function login(username: string, password: string) {
+  const userService = await useUserService();
+
+  const userID = await userService.login(username, password);
+  return new Response(userID);
+}
+
+export const userInfo = async (userID: string) => {
+  //
+};

+ 6 - 0
src/apis/hooks/context.ts

@@ -0,0 +1,6 @@
+import { Context } from "@midwayjs/koa";
+import { useContext as useCtx } from "@midwayjs/hooks";
+
+export default function useContext() {
+  return useCtx<Context>();
+}

+ 14 - 0
src/apis/hooks/service.ts

@@ -0,0 +1,14 @@
+import UserService from "@/apis/service/user";
+import { useInject } from "@midwayjs/hooks";
+import { isNil } from "lodash";
+
+let userService: UserService;
+
+export async function useUserService() {
+  if (isNil(userService)) {
+    userService = await useInject(UserService);
+  }
+  return userService;
+}
+
+export async function useXXX() {}

+ 0 - 0
src/apis/middleware/.gitkeep


+ 21 - 0
src/apis/middleware/error.ts

@@ -0,0 +1,21 @@
+import useContext from "../hooks/context";
+import { IResult } from "@sc/types";
+import ErrNo from "@/constants/errorEnum";
+
+const error = async (next: any) => {
+  const ctx = useContext();
+  try {
+    await next();
+  } catch (err: any) {
+    console.log(err);
+    const errno = err.errno || ErrNo.ERROR;
+    const result: IResult = {
+      errno,
+      message: `${err.message}`,
+      data: null,
+    };
+    ctx.status = 400;
+    ctx.body = result;
+  }
+};
+export default error;

+ 0 - 0
src/apis/service/.gitkeep


+ 13 - 0
src/apis/service/user.ts

@@ -0,0 +1,13 @@
+import { Provide } from "@midwayjs/decorator";
+import AppError from "@/utils/common/AppError";
+import ErrNo from "@/constants/errorEnum";
+
+@Provide()
+export default class UserService {
+  async login(username: string, password: string) {
+    if (username === "zhangsan" && password === "123") {
+      return "userID:zhangsan-123";
+    }
+    throw new AppError("用户名或密码错误", ErrNo.LOGIN_FAIL);
+  }
+}

+ 9 - 0
src/constants/errorEnum.ts

@@ -0,0 +1,9 @@
+enum ErrNo {
+  NO_ERROR = 0,
+  // 没捕获到的通用错误
+  ERROR = 1,
+  /* 用户相关错误(包含登录) 1001 - 1999 */
+  LOGIN_FAIL = 10001,
+}
+
+export default ErrNo;

+ 26 - 0
src/main.ts

@@ -5,9 +5,35 @@ import zhCn from "element-plus/es/locale/lang/zh-cn";
 import "@/styles/index.scss";
 import router from "./router";
 import register from "@/components";
+import { defaults, ApiParam } from "@midwayjs/hooks/request";
+import axios from "axios";
 
 const app = createApp(App);
 app.use(ElementPlus, { size: "mini", locale: zhCn });
 app.use(router);
 register(app);
 app.mount("#app");
+
+// 前端自定义 SDK
+
+// 添加响应拦截器
+axios.interceptors.response.use(
+  (response) => {
+    // 2xx 范围内的状态码都会触发该函数。
+    // 对响应数据做点什么
+    return response;
+  },
+  (error) => {
+    // 超出 2xx 范围的状态码都会触发该函数。
+    // 对响应错误做点什么
+    if (error.response) {
+      return Promise.reject(error.response.data);
+    }
+    return Promise.reject(error);
+  }
+);
+// 使用 Axios 作为 HTTP 请求的客户端
+defaults.request = async (param: ApiParam) => {
+  const resp = await axios(param);
+  return resp.data;
+};

+ 14 - 0
src/utils/common/AppError.ts

@@ -0,0 +1,14 @@
+import ErrNo from "@/constants/errorEnum";
+
+export default class AppError extends Error {
+  errno = ErrNo.ERROR;
+
+  constructor(message: string, errno?: ErrNo) {
+    super(message);
+    if (errno) {
+      this.errno = errno;
+    } else {
+      this.errno = ErrNo.ERROR;
+    }
+  }
+}

+ 15 - 0
src/utils/common/Response.ts

@@ -0,0 +1,15 @@
+import ErrNo from "@/constants/errorEnum";
+
+export default class Response<T> {
+  data: T;
+
+  errno: ErrNo;
+
+  message: string;
+
+  constructor(data: T, errno = ErrNo.NO_ERROR, message = "success") {
+    this.data = data;
+    this.errno = errno;
+    this.message = message;
+  }
+}

+ 35 - 24
src/views/login/Login.vue

@@ -1,27 +1,28 @@
 <script setup lang="ts">
 import { onMounted, ref } from "vue";
-import useRotateCanvas from "./scripts/rotateCanvas";
-import usePreloadImg from "./scripts/preloadImg";
-import useModuleItem from "./scripts/moduleItem";
-
-// video 元素的模板引用
-const loginVideoRef = ref<HTMLVideoElement>();
-
-// 设置视频播放速度
-const setVideoRate = (rate = 1) => {
-  if (loginVideoRef.value) loginVideoRef.value.playbackRate = rate;
-};
-
-onMounted(() => {
-  // 设置视频播放速度
-  // setVideoRate();
-  // 预加载 模块item hover图片
-  usePreloadImg();
-});
+import useRotateCanvas from "./scripts/useRotateCanvas";
+import usePreloadImg from "./scripts/usePreloadImg";
+import useModuleItem from "./scripts/useModuleItem";
+import { login } from "@/apis/controller/user";
 
+// 预加载 模块item hover图片
+onMounted(() => usePreloadImg());
 // 底部旋转 canvas
 const { canvasRef } = useRotateCanvas();
 const { moduleRef } = useModuleItem();
+
+const username = ref("");
+const password = ref("");
+
+const handleSubmit = async () => {
+  console.log("你好");
+  try {
+    const userID = await login(username.value, password.value);
+    console.log("用户 ID", userID);
+  } catch (err: any) {
+    console.log("次哦判断是否", err.errno);
+  }
+};
 </script>
 
 <template>
@@ -52,20 +53,30 @@ const { moduleRef } = useModuleItem();
       <div class="panel">
         <!-- 用户名 -->
         <div class="input-wrap username">
-          <input class="input" type="text" placeholder="用户名" />
+          <input
+            class="input"
+            type="text"
+            placeholder="用户名"
+            v-model="username"
+          />
           <i class="line" />
         </div>
         <!-- 密码 -->
         <div class="input-wrap password">
-          <input class="input" type="password" placeholder="密码" />
+          <input
+            class="input"
+            type="password"
+            placeholder="密码"
+            v-model="password"
+          />
           <i class="line" />
         </div>
         <!-- 登录按钮 -->
         <div class="login-btn">
-          <button class="button">登录</button>
-          <div class="flash-wrap">
-            <div class="flash"></div>
-          </div>
+          <button class="button" @click="handleSubmit">登录</button>
+          <!--          <div class="flash-wrap">-->
+          <!--            <div class="flash"></div>-->
+          <!--          </div>-->
         </div>
       </div>
       <!-- 旋转光圈 -->

src/views/login/scripts/moduleItem.ts → src/views/login/scripts/useModuleItem.ts


src/views/login/scripts/preloadImg.ts → src/views/login/scripts/usePreloadImg.ts