(
+ url: string,
+ params?: AxiosRequestConfig,
+ config?: AxiosRequestConfig
+ ): Promise {
+ return this.request('post', url, params, config)
+ }
+
+ /** 单独抽离的`get`工具函数 */
+ public get(
+ url: string,
+ params?: AxiosRequestConfig,
+ config?: AxiosRequestConfig
+ ): Promise {
+ return this.request('get', url, params, config)
+ }
+}
+
+export const http = new Http()
diff --git a/frontend/src/utils/http/types.d.ts b/frontend/src/utils/http/types.d.ts
new file mode 100644
index 0000000..e79c34e
--- /dev/null
+++ b/frontend/src/utils/http/types.d.ts
@@ -0,0 +1,43 @@
+import type {
+ Method,
+ AxiosError,
+ AxiosResponse,
+ AxiosRequestConfig
+} from "axios";
+
+export type RequestMethods = Extract<
+ Method,
+ "get" | "post" | "put" | "delete" | "patch" | "option" | "head"
+>;
+
+export interface HttpError extends AxiosError {
+ isCancelRequest?: boolean;
+}
+
+export interface HttpResponse extends AxiosResponse {
+ config: HttpRequestConfig;
+}
+
+export interface HttpRequestConfig extends AxiosRequestConfig {
+ beforeRequestCallback?: (request: HttpRequestConfig) => void;
+ beforeResponseCallback?: (response: HttpResponse) => void;
+}
+
+export default class Http {
+ request(
+ method: RequestMethods,
+ url: string,
+ param?: AxiosRequestConfig,
+ axiosConfig?: HttpRequestConfig
+ ): Promise;
+ post(
+ url: string,
+ params?: T,
+ config?: HttpRequestConfig
+ ): Promise;
+ get(
+ url: string,
+ params?: T,
+ config?: HttpRequestConfig
+ ): Promise;
+}
diff --git a/frontend/src/views/friend/hook.tsx b/frontend/src/views/friend/hook.tsx
new file mode 100644
index 0000000..ed9ecf4
--- /dev/null
+++ b/frontend/src/views/friend/hook.tsx
@@ -0,0 +1,25 @@
+import { onMounted, ref } from 'vue'
+
+import { type ContactItem, getFriendList } from '@/api/contact'
+
+// 起飞
+export function useHook() {
+ const dataList = ref([]);
+
+ // 获取数据
+ async function onSearch() {
+ const { data } = await getFriendList();
+ dataList.value = data;
+ console.log(data);
+ }
+
+ // 挂载时执行
+ onMounted(() => {
+ onSearch();
+ });
+
+ return {
+ dataList,
+ onSearch
+ }
+}
diff --git a/frontend/src/views/friend/index.vue b/frontend/src/views/friend/index.vue
index 96c92b8..9f7135b 100644
--- a/frontend/src/views/friend/index.vue
+++ b/frontend/src/views/friend/index.vue
@@ -1,12 +1,47 @@
-
- 好友列表
-
+
+ -
+
+
+
+
+
+
{{ item.Nickname }}
+
在通讯录
+
不在通讯录
+
+
+
+
+
- 原始微信Id
微信号
+
-
+
{{ item.Wxid }}
+ {{ item.CustomAccount }}
+
+
+
+
- 最后活跃时间
+
-
+
+ {{ item.LastActive }}
+
+
+
+
+
+
+
diff --git a/frontend/src/views/index/index.vue b/frontend/src/views/index/index.vue
index aa5db8e..fe547e4 100644
--- a/frontend/src/views/index/index.vue
+++ b/frontend/src/views/index/index.vue
@@ -7,6 +7,6 @@ defineOptions({
- 首页
+ 首页
diff --git a/frontend/tailwind.config.js b/frontend/tailwind.config.js
new file mode 100644
index 0000000..58bfb30
--- /dev/null
+++ b/frontend/tailwind.config.js
@@ -0,0 +1,12 @@
+/** @type {import('tailwindcss').Config} */
+export default {
+ content: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx,md}'],
+ theme: {
+ container: {
+ center: true,
+ padding: '2rem',
+ },
+ },
+ plugins: [require('daisyui'), require('@tailwindcss/forms'),],
+}
+
diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts
index 36c6187..fabee0d 100644
--- a/frontend/vite.config.ts
+++ b/frontend/vite.config.ts
@@ -6,6 +6,16 @@ import vueJsx from '@vitejs/plugin-vue-jsx'
// https://vitejs.dev/config/
export default defineConfig({
+ server: {
+ proxy: {
+ "/api": {
+ // target: "https://graduate.frps.ltd",
+ target: "http://127.0.0.1:8080",
+ changeOrigin: true
+ // rewrite: path => path.replace(/^\/api/, "")
+ }
+ },
+ },
plugins: [
vue(),
vueJsx(),
diff --git a/views/friend.html b/views/friend.html
index e97c719..856635d 100644
--- a/views/friend.html
+++ b/views/friend.html
@@ -21,6 +21,7 @@
+
{{ range .friends }}
-
diff --git a/views/index.html b/views/index.html
index d0bfbf7..8a5dbc5 100644
--- a/views/index.html
+++ b/views/index.html
@@ -21,6 +21,7 @@