From 8d11a6affcfa37344011a6aaf3d6e005546f0e61 Mon Sep 17 00:00:00 2001 From: Soybean Date: Sat, 30 Jul 2022 22:16:42 +0800 Subject: [PATCH] =?UTF-8?q?feat(projects):=20=E6=B7=BB=E5=8A=A0=E8=AF=B7?= =?UTF-8?q?=E6=B1=82=E9=80=82=E9=85=8Dadapter=E5=B1=82=E5=BA=94=E7=94=A8?= =?UTF-8?q?=E7=9A=84=E7=A4=BA=E4=BE=8B=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 17 ++++--- mock/api/index.ts | 3 +- mock/api/management.ts | 51 +++++++++++++++++++ src/enum/business.ts | 6 +++ src/hooks/business/useNaiveTable.ts | 70 +-------------------------- src/hooks/common/useBoolean.ts | 4 ++ src/service/api/index.ts | 1 + src/service/api/management.adapter.ts | 39 +++++++++++++++ src/service/api/management.ts | 22 +++++++++ src/typings/api.d.ts | 21 ++++++++ src/typings/business.d.ts | 20 ++++++++ src/typings/utils.d.ts | 10 +--- src/views/management/user/index.vue | 50 ++++++++++++++++++- src/views/management/user/user.ts | 0 14 files changed, 228 insertions(+), 86 deletions(-) create mode 100644 mock/api/management.ts create mode 100644 src/service/api/management.adapter.ts create mode 100644 src/service/api/management.ts create mode 100644 src/views/management/user/user.ts diff --git a/README.md b/README.md index 0e4e130a..7d39eb9e 100644 --- a/README.md +++ b/README.md @@ -7,13 +7,13 @@ ## 简介 -Soybean Admin 是一个基于 Vue3、Vite3、TypeScript、Naive UI和UnoCSS 的清新优雅的中后台模版,它使用了最新的前端技术栈,内置丰富的主题配置,有着极高的代码规范,基于mock实现的动态权限路由,开箱即用的中后台前端解决方案,也可用于学习参考。 +[Soybean Admin](https://github.com/honghuangdc/soybean-admin) 是一个基于 Vue3、Vite3、TypeScript、NaiveUI、Pinia和UnoCSS 的清新优雅的中后台模版,它使用了最新的前端技术栈,内置丰富的主题配置,有着极高的代码规范,基于mock实现的动态权限路由,开箱即用的中后台前端解决方案,也可用于学习参考。 ## 特性 -- **最新技术栈**:使用 Vue3/vite3 等前端前沿技术开发, 使用高效率的npm包管理器pnpm +- **最新技术栈**:使用 Vue3/Vite3 等前端前沿技术开发, 使用高效率的npm包管理器pnpm - **TypeScript**:应用程序级 JavaScript 的语言 -- **主题**:丰富可配置的主题、暗黑模式,基于原子css - UnoCSS的动态主题颜色 +- **主题**:丰富可配置的主题、暗黑模式,基于原子css框架 - UnoCSS的动态主题颜色 - **代码规范**:丰富的规范插件及极高的代码规范 - **权限路由**:简易的路由配置、基于mock的动态路由能快速实现后端动态路由 - **请求函数**:基于axios的完善的请求函数封装,提供Promise和hooks两种请求函数,加入请求结果数据转换的适配器 @@ -94,6 +94,14 @@ Soybean Admin 是一个基于 Vue3、Vite3、TypeScript、Naive UI和UnoCSS 的 ## 安装使用 +- 环境配置 + + **本地环境需要安装 pnpm 7.x 、Node.js 14.18+ 和 Git** + - [Nodejs安装教程]() + + - [Nodejs版本管理工具fnm安装教程]() + + - 克隆代码 ```bash @@ -118,9 +126,6 @@ pnpm dev pnpm build ``` -**本地环境需要安装 pnpm 6.x 、Node.js 14.x 和 Git** - - ## 如何贡献 非常欢迎您的加入![提一个 Issue](https://github.com/honghuangdc/soybean-admin/issues/new) 或者提交一个 Pull Request。 diff --git a/mock/api/index.ts b/mock/api/index.ts index 0a5df64a..32a3dcce 100644 --- a/mock/api/index.ts +++ b/mock/api/index.ts @@ -1,4 +1,5 @@ import auth from './auth'; import route from './route'; +import management from './management'; -export default [...auth, ...route]; +export default [...auth, ...route, ...management]; diff --git a/mock/api/management.ts b/mock/api/management.ts new file mode 100644 index 00000000..e196be16 --- /dev/null +++ b/mock/api/management.ts @@ -0,0 +1,51 @@ +import type { MockMethod } from 'vite-plugin-mock'; + +const apis: MockMethod[] = [ + { + url: '/mock/getUserManagementList', + method: 'post', + response: (): Service.MockServiceResult => { + const data: ApiUserManagement.UserTable[] = [ + { + id: '1', + name: '张三', + age: 24, + gender: null, + createTime: '2022-04-13', + updateTime: '2022-07-29' + }, + { + id: '2', + name: '李四', + age: 22, + gender: '1', + createTime: '2022-05-13', + updateTime: '2022-06-29' + }, + { + id: '3', + name: '王五', + gender: '1', + createTime: '2022-04-18', + updateTime: '2022-07-30' + }, + { + id: '4', + name: '王小梅', + age: 20, + gender: '0', + createTime: '2022-05-18', + updateTime: '2022-07-30' + } + ]; + + return { + code: 200, + message: 'ok', + data + }; + } + } +]; + +export default apis; diff --git a/src/enum/business.ts b/src/enum/business.ts index b479cf5d..bd427040 100644 --- a/src/enum/business.ts +++ b/src/enum/business.ts @@ -13,3 +13,9 @@ export enum EnumLoginModule { 'reset-pwd' = '重置密码', 'bind-wechat' = '微信绑定' } + +export enum EnumGender { + male = '男', + female = '女', + null = '' +} diff --git a/src/hooks/business/useNaiveTable.ts b/src/hooks/business/useNaiveTable.ts index 18e62805..68e3f65c 100644 --- a/src/hooks/business/useNaiveTable.ts +++ b/src/hooks/business/useNaiveTable.ts @@ -1,69 +1 @@ -import type { DataTableColumn } from 'naive-ui'; - -type UnionColumn = T extends DataTableColumn[] ? TypeUtil.ArrayToUnion : never; - -type ColumnKey = 'key'; - -type InterfaceArray = { - [key: string]: unknown; -}; - -type ColumnKeyData = { - key: unknown; -}; - -type ExcludeArrayByKey = T extends [infer First, ...infer Rest] - ? First extends ColumnKeyData - ? Rest extends InterfaceArray[] - ? [First, ...ExcludeArrayByKey] - : [First] - : Rest extends InterfaceArray[] - ? ExcludeArrayByKey - : [] - : []; - -type GetUnionColumnKey = ColumnKey extends keyof UnionColumn - ? UnionColumn[ColumnKey] - : never; - -export const columns: DataTableColumn[] = [ - { - type: 'selection' - }, - { - title: 'Name', - key: 'name', - align: 'center' - }, - { - title: 'Age', - key: 'age' - }, - { - title: 'Address', - key: 'address' - } -]; - -export type UnionColumnKey = GetUnionColumnKey< - ExcludeArrayByKey< - [ - { - type: 'selection'; - }, - { - title: 'Name'; - key: 'name'; - align: 'center'; - }, - { - title: 'Age'; - key: 'age'; - }, - { - title: 'Address'; - key: 'address'; - } - ] - > ->; +// import type { DataTableColumn } from 'naive-ui'; diff --git a/src/hooks/common/useBoolean.ts b/src/hooks/common/useBoolean.ts index 31c34aaf..c03db357 100644 --- a/src/hooks/common/useBoolean.ts +++ b/src/hooks/common/useBoolean.ts @@ -1,5 +1,9 @@ import { ref } from 'vue'; +/** + * boolean组合式函数 + * @param initValue 初始值 + */ export default function useBoolean(initValue = false) { const bool = ref(initValue); diff --git a/src/service/api/index.ts b/src/service/api/index.ts index a2c76b1c..06bf701c 100644 --- a/src/service/api/index.ts +++ b/src/service/api/index.ts @@ -1,2 +1,3 @@ export * from './auth'; export * from './demo'; +export * from './management'; diff --git a/src/service/api/management.adapter.ts b/src/service/api/management.adapter.ts new file mode 100644 index 00000000..8ac43aaa --- /dev/null +++ b/src/service/api/management.adapter.ts @@ -0,0 +1,39 @@ +import { EnumGender } from '@/enum'; +import { isUndefined } from '@/utils'; + +export function adapterOfFetchUserManagementList( + requestData: ApiUserManagement.UserTable[], + adminId: string +): UserManagement.UserTable[] { + const genderMap: Record< + NonNullable, + NonNullable + > = { + '0': 'female', + '1': 'male' + }; + + // 1. 有可能依赖于多个接口的结果,再转换成页面的数据 + // 2. 接口定义的字段有可能为null, 例如 预期是数组却返回了null,导致调用数组方法报错 + // 3. 字段可能丢失 + + return requestData.map(item => { + const { id, name, age, gender } = item; + + const userName = name + (adminId === id ? '(管理员)' : ''); + + const userAge = isUndefined(age) ? '无' : String(age); + + const userGender = gender !== null ? genderMap[gender] : 'null'; + + const result: UserManagement.UserTable = { + id, + userName, + userAge, + userGender, + userGenderLabel: EnumGender[userGender] + }; + + return result; + }); +} diff --git a/src/service/api/management.ts b/src/service/api/management.ts new file mode 100644 index 00000000..9336d95b --- /dev/null +++ b/src/service/api/management.ts @@ -0,0 +1,22 @@ +import { adapter } from '@/utils'; +import { mockRequest } from '../request'; +import { adapterOfFetchUserManagementList } from './management.adapter'; + +/** + * 获取用户管理列表 + */ +export async function fetchUserManagementList() { + const data = await mockRequest.post('/getUserManagementList'); + + const id = '2'; + + return adapter(adapterOfFetchUserManagementList, data, { error: null, data: id }); +} + +// export async function fetchFilterUserManagementList( +// filterKey: keyof UserManagement.UserTable, +// mode: 'fontEnd' | 'backEnd', +// source: UserManagement.UserTable[] +// ) { + +// } diff --git a/src/typings/api.d.ts b/src/typings/api.d.ts index 432b3666..3f2d16e9 100644 --- a/src/typings/api.d.ts +++ b/src/typings/api.d.ts @@ -28,3 +28,24 @@ declare namespace ApiDemo { dataName: string; } } + +declare namespace ApiUserManagement { + interface UserTable { + /** 用户id */ + id: string; + /** 用户名 */ + name: string; + /** 用户年龄 */ + age?: number; + /** + * 用户性别 + * - 男 1 + * - 女 0 + */ + gender: '0' | '1' | null; + /** 创建时间 */ + createTime: string; + /** 更新时间 */ + updateTime: string; + } +} diff --git a/src/typings/business.d.ts b/src/typings/business.d.ts index 70bda08d..1949a380 100644 --- a/src/typings/business.d.ts +++ b/src/typings/business.d.ts @@ -62,3 +62,23 @@ declare namespace Message { tagProps?: import('naive-ui').TagProps; } } + +/** 用户管理 */ +declare namespace UserManagement { + /** 用户表格 */ + interface UserTable { + /** 用户id */ + id: string; + /** 用户名 */ + userName: string; + /** 用户年龄 */ + userAge: string; + /** + * 用户性别 + * - male 男 + * - female 女 + */ + userGender: keyof typeof import('@/enum').EnumGender; + userGenderLabel: import('@/enum').EnumGender; + } +} diff --git a/src/typings/utils.d.ts b/src/typings/utils.d.ts index 31a975ad..87550f90 100644 --- a/src/typings/utils.d.ts +++ b/src/typings/utils.d.ts @@ -7,15 +7,9 @@ declare namespace TypeUtil { type GetFunReturn = F extends (...args: any) => infer R ? R : never; + type Writable = { [K in keyof T]: T[K] }; + type FirstOfArray = T extends [infer First, ...infer _Rest] ? First : never; type LastOfArray = T extends [...infer _Rest, infer Last] ? Last : never; - - type ArrayToUnion = T extends [infer First, ...infer Rest] - ? First extends any - ? Rest extends any[] - ? FirstOfArray<[First]> | ArrayToUnion - : [First] - : never - : never; } diff --git a/src/views/management/user/index.vue b/src/views/management/user/index.vue index 4780bbe4..b7d49a7a 100644 --- a/src/views/management/user/index.vue +++ b/src/views/management/user/index.vue @@ -1,9 +1,55 @@ - + diff --git a/src/views/management/user/user.ts b/src/views/management/user/user.ts new file mode 100644 index 00000000..e69de29b