版本升级:
1. 修复(kinit-api):utils/cache.py 日志模块导入问题修复 2. 修复(kinit-api):token解析失败会报错问题修复 3. 优化(kinit-api):用户登录认证失败返回值优化 4. 优化(kinit-api):获取redis方式统一改为redis_getter(request) 5. 优化(kini-api):文件IO修改为异步操作 6. 优化(kinit-api):关联创建人时将user_id改为create_user_id 7. 文档(kinit-api):kinit-api/README.md 加入查询数据文档 8. 修复(kinit-admin):用户无法导出问题修复 9. 优化(kinit-admin):角色新增与编辑框使用默认父子联动 10. 更新(kinit-admin):usePermissionStore 改为 useRouterStoreWithOut,因为此文件主要记录路由 11. 更新(kinit-admin):取消用户信息的持久化存储,改为仅保存在pinia store共享中,并添加roles,permissions信息 12. 修复(kinit-admin):菜单新增与编辑框,目录与菜单切换时会出现抖动问题修复 13. 优化(kinit-admin):src\hooks\web\useTable.ts 优化删除数据方法 14. 优化(kinit-admin):config/services.ts 新增返回403状态码时直接退出系统 15. 优化(kinit-admin):将store中的本文件使用store调用的,改为this 16. 更新(kinit-admin):路由拦截更新 17. 更新(kinit-api,kinit-admin,kinit-uni):取消接口地址最后面的 /
This commit is contained in:
parent
71dc166516
commit
c65ff06918
@ -7,17 +7,17 @@ import type {
|
|||||||
} from './types'
|
} from './types'
|
||||||
|
|
||||||
export const getBannersApi = (): Promise<IResponse<AnalysisBannersTypes[]>> => {
|
export const getBannersApi = (): Promise<IResponse<AnalysisBannersTypes[]>> => {
|
||||||
return request.get({ url: '/vadmin/analysis/banners/' })
|
return request.get({ url: '/vadmin/analysis/banners' })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getUserAccessSourceApi = (): Promise<IResponse<UserAccessSource[]>> => {
|
export const getUserAccessSourceApi = (): Promise<IResponse<UserAccessSource[]>> => {
|
||||||
return request.get({ url: '/vadmin/analysis/user/access/source/' })
|
return request.get({ url: '/vadmin/analysis/user/access/source' })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getWeeklyUserActivityApi = (): Promise<IResponse<WeeklyUserActivity[]>> => {
|
export const getWeeklyUserActivityApi = (): Promise<IResponse<WeeklyUserActivity[]>> => {
|
||||||
return request.get({ url: '/vadmin/analysis/weekly/user/activity/' })
|
return request.get({ url: '/vadmin/analysis/weekly/user/activity' })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getMonthlySalesApi = (): Promise<IResponse<MonthlySales[]>> => {
|
export const getMonthlySalesApi = (): Promise<IResponse<MonthlySales[]>> => {
|
||||||
return request.get({ url: '/vadmin/analysis/monthly/sales/' })
|
return request.get({ url: '/vadmin/analysis/monthly/sales' })
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import request from '@/config/axios'
|
import request from '@/config/axios'
|
||||||
|
|
||||||
export const getUserLoginDistributeApi = (): Promise<IResponse> => {
|
export const getUserLoginDistributeApi = (): Promise<IResponse> => {
|
||||||
return request.get({ url: '/vadmin/record/analysis/user/login/distribute/' })
|
return request.get({ url: '/vadmin/record/analysis/user/login/distribute' })
|
||||||
}
|
}
|
||||||
|
@ -2,25 +2,25 @@ import request from '@/config/axios'
|
|||||||
import type { WorkplaceTotal, Project, Dynamic, Team, RadarData, Shortcuts } from './types'
|
import type { WorkplaceTotal, Project, Dynamic, Team, RadarData, Shortcuts } from './types'
|
||||||
|
|
||||||
export const getCountApi = (): Promise<IResponse<WorkplaceTotal>> => {
|
export const getCountApi = (): Promise<IResponse<WorkplaceTotal>> => {
|
||||||
return request.get({ url: '/vadmin/workplace/total/' })
|
return request.get({ url: '/vadmin/workplace/total' })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getProjectApi = (): Promise<IResponse<Project>> => {
|
export const getProjectApi = (): Promise<IResponse<Project>> => {
|
||||||
return request.get({ url: '/vadmin/workplace/project/' })
|
return request.get({ url: '/vadmin/workplace/project' })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getDynamicApi = (): Promise<IResponse<Dynamic[]>> => {
|
export const getDynamicApi = (): Promise<IResponse<Dynamic[]>> => {
|
||||||
return request.get({ url: '/vadmin/workplace/dynamic/' })
|
return request.get({ url: '/vadmin/workplace/dynamic' })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getTeamApi = (): Promise<IResponse<Team[]>> => {
|
export const getTeamApi = (): Promise<IResponse<Team[]>> => {
|
||||||
return request.get({ url: '/vadmin/workplace/team/' })
|
return request.get({ url: '/vadmin/workplace/team' })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getRadarApi = (): Promise<IResponse<RadarData[]>> => {
|
export const getRadarApi = (): Promise<IResponse<RadarData[]>> => {
|
||||||
return request.get({ url: '/vadmin/workplace/radar/' })
|
return request.get({ url: '/vadmin/workplace/radar' })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getShortcutsApi = (): Promise<IResponse<Shortcuts[]>> => {
|
export const getShortcutsApi = (): Promise<IResponse<Shortcuts[]>> => {
|
||||||
return request.get({ url: '/vadmin/workplace/shortcuts/' })
|
return request.get({ url: '/vadmin/workplace/shortcuts' })
|
||||||
}
|
}
|
||||||
|
@ -2,13 +2,13 @@ import request from '@/config/axios'
|
|||||||
import type { UserLoginType } from './types'
|
import type { UserLoginType } from './types'
|
||||||
|
|
||||||
export const loginApi = (data: UserLoginType): Promise<IResponse> => {
|
export const loginApi = (data: UserLoginType): Promise<IResponse> => {
|
||||||
return request.post({ url: '/auth/login/', data })
|
return request.post({ url: '/auth/login', data })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getRoleMenusApi = (): Promise<IResponse<AppCustomRouteRecordRaw[]>> => {
|
export const getRoleMenusApi = (): Promise<IResponse<AppCustomRouteRecordRaw[]>> => {
|
||||||
return request.get({ url: '/auth/getMenuList/' })
|
return request.get({ url: '/auth/getMenuList' })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const postSMSCodeApi = (params: any): Promise<IResponse> => {
|
export const postSMSCodeApi = (params: any): Promise<IResponse> => {
|
||||||
return request.post({ url: '/vadmin/system/sms/send/', params })
|
return request.post({ url: '/vadmin/system/sms/send', params })
|
||||||
}
|
}
|
||||||
|
@ -2,25 +2,25 @@ import request from '@/config/axios'
|
|||||||
import { List } from 'echarts'
|
import { List } from 'echarts'
|
||||||
|
|
||||||
export const getMenuListApi = (params: any): Promise<IResponse> => {
|
export const getMenuListApi = (params: any): Promise<IResponse> => {
|
||||||
return request.get({ url: '/vadmin/auth/menus/', params })
|
return request.get({ url: '/vadmin/auth/menus', params })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const delMenuListApi = (data: List): Promise<IResponse> => {
|
export const delMenuListApi = (data: List): Promise<IResponse> => {
|
||||||
return request.delete({ url: '/vadmin/auth/menus/', data })
|
return request.delete({ url: '/vadmin/auth/menus', data })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const addMenuListApi = (data: any): Promise<IResponse> => {
|
export const addMenuListApi = (data: any): Promise<IResponse> => {
|
||||||
return request.post({ url: '/vadmin/auth/menus/', data })
|
return request.post({ url: '/vadmin/auth/menus', data })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const putMenuListApi = (data: any): Promise<IResponse> => {
|
export const putMenuListApi = (data: any): Promise<IResponse> => {
|
||||||
return request.put({ url: `/vadmin/auth/menus/${data.id}/`, data })
|
return request.put({ url: `/vadmin/auth/menus/${data.id}`, data })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getMenuTreeOptionsApi = (): Promise<IResponse> => {
|
export const getMenuTreeOptionsApi = (): Promise<IResponse> => {
|
||||||
return request.get({ url: '/vadmin/auth/menus/tree/options/' })
|
return request.get({ url: '/vadmin/auth/menus/tree/options' })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getMenuRoleTreeOptionsApi = (): Promise<IResponse> => {
|
export const getMenuRoleTreeOptionsApi = (): Promise<IResponse> => {
|
||||||
return request.get({ url: '/vadmin/auth/menus/role/tree/options/' })
|
return request.get({ url: '/vadmin/auth/menus/role/tree/options' })
|
||||||
}
|
}
|
||||||
|
@ -1,25 +1,25 @@
|
|||||||
import request from '@/config/axios'
|
import request from '@/config/axios'
|
||||||
|
|
||||||
export const getRoleListApi = (params: any): Promise<IResponse> => {
|
export const getRoleListApi = (params: any): Promise<IResponse> => {
|
||||||
return request.get({ url: '/vadmin/auth/roles/', params })
|
return request.get({ url: '/vadmin/auth/roles', params })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const addRoleListApi = (data: any): Promise<IResponse> => {
|
export const addRoleListApi = (data: any): Promise<IResponse> => {
|
||||||
return request.post({ url: '/vadmin/auth/roles/', data })
|
return request.post({ url: '/vadmin/auth/roles', data })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const delRoleListApi = (data: any): Promise<IResponse> => {
|
export const delRoleListApi = (data: any): Promise<IResponse> => {
|
||||||
return request.delete({ url: '/vadmin/auth/roles/', data })
|
return request.delete({ url: '/vadmin/auth/roles', data })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const putRoleListApi = (data: any): Promise<IResponse> => {
|
export const putRoleListApi = (data: any): Promise<IResponse> => {
|
||||||
return request.put({ url: `/vadmin/auth/roles/${data.id}/`, data })
|
return request.put({ url: `/vadmin/auth/roles/${data.id}`, data })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getRoleApi = (dataId: number): Promise<IResponse> => {
|
export const getRoleApi = (dataId: number): Promise<IResponse> => {
|
||||||
return request.get({ url: `/vadmin/auth/roles/${dataId}/` })
|
return request.get({ url: `/vadmin/auth/roles/${dataId}` })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getRoleOptionsApi = (): Promise<IResponse> => {
|
export const getRoleOptionsApi = (): Promise<IResponse> => {
|
||||||
return request.get({ url: `/vadmin/auth/roles/options/` })
|
return request.get({ url: `/vadmin/auth/roles/options` })
|
||||||
}
|
}
|
||||||
|
@ -1,57 +1,57 @@
|
|||||||
import request from '@/config/axios'
|
import request from '@/config/axios'
|
||||||
|
|
||||||
export const getUserListApi = (params: any): Promise<IResponse> => {
|
export const getUserListApi = (params: any): Promise<IResponse> => {
|
||||||
return request.get({ url: '/vadmin/auth/users/', params })
|
return request.get({ url: '/vadmin/auth/users', params })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const addUserListApi = (data: any): Promise<IResponse> => {
|
export const addUserListApi = (data: any): Promise<IResponse> => {
|
||||||
return request.post({ url: '/vadmin/auth/users/', data })
|
return request.post({ url: '/vadmin/auth/users', data })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const delUserListApi = (data: any): Promise<IResponse> => {
|
export const delUserListApi = (data: any): Promise<IResponse> => {
|
||||||
return request.delete({ url: '/vadmin/auth/users/', data })
|
return request.delete({ url: '/vadmin/auth/users', data })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const putUserListApi = (data: any): Promise<IResponse> => {
|
export const putUserListApi = (data: any): Promise<IResponse> => {
|
||||||
return request.put({ url: `/vadmin/auth/users/${data.id}/`, data })
|
return request.put({ url: `/vadmin/auth/users/${data.id}`, data })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getUserApi = (dataId: number): Promise<IResponse> => {
|
export const getUserApi = (dataId: number): Promise<IResponse> => {
|
||||||
return request.get({ url: `/vadmin/auth/users/${dataId}/` })
|
return request.get({ url: `/vadmin/auth/users/${dataId}` })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const postCurrentUserResetPassword = (data: any): Promise<IResponse> => {
|
export const postCurrentUserResetPassword = (data: any): Promise<IResponse> => {
|
||||||
return request.post({ url: `/vadmin/auth/user/current/reset/password/`, data })
|
return request.post({ url: `/vadmin/auth/user/current/reset/password`, data })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const postCurrentUserUpdateInfo = (data: any): Promise<IResponse> => {
|
export const postCurrentUserUpdateInfo = (data: any): Promise<IResponse> => {
|
||||||
return request.post({ url: `/vadmin/auth/user/current/update/info/`, data })
|
return request.post({ url: `/vadmin/auth/user/current/update/info`, data })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getCurrentAdminUserInfo = (): Promise<IResponse> => {
|
export const getCurrentAdminUserInfo = (): Promise<IResponse> => {
|
||||||
return request.get({ url: `/vadmin/auth/user/admin/current/info/` })
|
return request.get({ url: `/vadmin/auth/user/admin/current/info` })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const postExportUserQueryListApi = (params: any, data: any): Promise<IResponse> => {
|
export const postExportUserQueryListApi = (params: any, data: any): Promise<IResponse> => {
|
||||||
return request.post({ url: `/vadmin/auth/user/export/query/list/to/excel/`, params, data })
|
return request.post({ url: `/vadmin/auth/user/export/query/list/to/excel`, params, data })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getImportTemplateApi = (): Promise<IResponse> => {
|
export const getImportTemplateApi = (): Promise<IResponse> => {
|
||||||
return request.get({ url: `/vadmin/auth/user/download/import/template/` })
|
return request.get({ url: `/vadmin/auth/user/download/import/template` })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const postImportUserApi = (data: any): Promise<IResponse> => {
|
export const postImportUserApi = (data: any): Promise<IResponse> => {
|
||||||
return request.post({
|
return request.post({
|
||||||
url: `/vadmin/auth/import/users/`,
|
url: `/vadmin/auth/import/users`,
|
||||||
headersType: 'multipart/form-data',
|
headersType: 'multipart/form-data',
|
||||||
data
|
data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const postUsersInitPasswordSendSMSApi = (data: any): Promise<IResponse> => {
|
export const postUsersInitPasswordSendSMSApi = (data: any): Promise<IResponse> => {
|
||||||
return request.post({ url: `/vadmin/auth/users/init/password/send/sms/`, data })
|
return request.post({ url: `/vadmin/auth/users/init/password/send/sms`, data })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const postUsersInitPasswordSendEmailApi = (data: any): Promise<IResponse> => {
|
export const postUsersInitPasswordSendEmailApi = (data: any): Promise<IResponse> => {
|
||||||
return request.post({ url: `/vadmin/auth/users/init/password/send/email/`, data })
|
return request.post({ url: `/vadmin/auth/users/init/password/send/email`, data })
|
||||||
}
|
}
|
||||||
|
@ -2,46 +2,46 @@ import request from '@/config/axios'
|
|||||||
|
|
||||||
// 常见问题类别
|
// 常见问题类别
|
||||||
export const getIssueCategoryListApi = (params: any): Promise<IResponse> => {
|
export const getIssueCategoryListApi = (params: any): Promise<IResponse> => {
|
||||||
return request.get({ url: '/vadmin/help/issue/categorys/', params })
|
return request.get({ url: '/vadmin/help/issue/categorys', params })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const addIssueCategoryApi = (data: any): Promise<IResponse> => {
|
export const addIssueCategoryApi = (data: any): Promise<IResponse> => {
|
||||||
return request.post({ url: '/vadmin/help/issue/categorys/', data })
|
return request.post({ url: '/vadmin/help/issue/categorys', data })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const delIssueCategoryListApi = (data: any): Promise<IResponse> => {
|
export const delIssueCategoryListApi = (data: any): Promise<IResponse> => {
|
||||||
return request.delete({ url: '/vadmin/help/issue/categorys/', data })
|
return request.delete({ url: '/vadmin/help/issue/categorys', data })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const putIssueCategoryApi = (data: any): Promise<IResponse> => {
|
export const putIssueCategoryApi = (data: any): Promise<IResponse> => {
|
||||||
return request.put({ url: `/vadmin/help/issue/categorys/${data.id}/`, data })
|
return request.put({ url: `/vadmin/help/issue/categorys/${data.id}`, data })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getIssueCategoryApi = (dataId: number): Promise<IResponse> => {
|
export const getIssueCategoryApi = (dataId: number): Promise<IResponse> => {
|
||||||
return request.get({ url: `/vadmin/help/issue/categorys/${dataId}/` })
|
return request.get({ url: `/vadmin/help/issue/categorys/${dataId}` })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getIssueCategoryOptionsApi = (): Promise<IResponse> => {
|
export const getIssueCategoryOptionsApi = (): Promise<IResponse> => {
|
||||||
return request.get({ url: `/vadmin/help/issue/categorys/options/` })
|
return request.get({ url: `/vadmin/help/issue/categorys/options` })
|
||||||
}
|
}
|
||||||
|
|
||||||
// 常见问题
|
// 常见问题
|
||||||
export const getIssueListApi = (params: any): Promise<IResponse> => {
|
export const getIssueListApi = (params: any): Promise<IResponse> => {
|
||||||
return request.get({ url: '/vadmin/help/issues/', params })
|
return request.get({ url: '/vadmin/help/issues', params })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const addIssueApi = (data: any): Promise<IResponse> => {
|
export const addIssueApi = (data: any): Promise<IResponse> => {
|
||||||
return request.post({ url: '/vadmin/help/issues/', data })
|
return request.post({ url: '/vadmin/help/issues', data })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const delIssueListApi = (data: any): Promise<IResponse> => {
|
export const delIssueListApi = (data: any): Promise<IResponse> => {
|
||||||
return request.delete({ url: '/vadmin/help/issues/', data })
|
return request.delete({ url: '/vadmin/help/issues', data })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const putIssueApi = (data: any): Promise<IResponse> => {
|
export const putIssueApi = (data: any): Promise<IResponse> => {
|
||||||
return request.put({ url: `/vadmin/help/issues/${data.id}/`, data })
|
return request.put({ url: `/vadmin/help/issues/${data.id}`, data })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getIssueApi = (dataId: number): Promise<IResponse> => {
|
export const getIssueApi = (dataId: number): Promise<IResponse> => {
|
||||||
return request.get({ url: `/vadmin/help/issues/${dataId}/` })
|
return request.get({ url: `/vadmin/help/issues/${dataId}` })
|
||||||
}
|
}
|
||||||
|
@ -1,49 +1,49 @@
|
|||||||
import request from '@/config/axios'
|
import request from '@/config/axios'
|
||||||
|
|
||||||
export const getDictTypeListApi = (params: any): Promise<IResponse> => {
|
export const getDictTypeListApi = (params: any): Promise<IResponse> => {
|
||||||
return request.get({ url: '/vadmin/system/dict/types/', params })
|
return request.get({ url: '/vadmin/system/dict/types', params })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const addDictTypeListApi = (data: any): Promise<IResponse> => {
|
export const addDictTypeListApi = (data: any): Promise<IResponse> => {
|
||||||
return request.post({ url: '/vadmin/system/dict/types/', data })
|
return request.post({ url: '/vadmin/system/dict/types', data })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const delDictTypeListApi = (data: any): Promise<IResponse> => {
|
export const delDictTypeListApi = (data: any): Promise<IResponse> => {
|
||||||
return request.delete({ url: '/vadmin/system/dict/types/', data })
|
return request.delete({ url: '/vadmin/system/dict/types', data })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const putDictTypeListApi = (data: any): Promise<IResponse> => {
|
export const putDictTypeListApi = (data: any): Promise<IResponse> => {
|
||||||
return request.put({ url: `/vadmin/system/dict/types/${data.id}/`, data })
|
return request.put({ url: `/vadmin/system/dict/types/${data.id}`, data })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getDictTypeApi = (dataId: number): Promise<IResponse> => {
|
export const getDictTypeApi = (dataId: number): Promise<IResponse> => {
|
||||||
return request.get({ url: `/vadmin/system/dict/types/${dataId}/` })
|
return request.get({ url: `/vadmin/system/dict/types/${dataId}` })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getDictTypeOptionsApi = (): Promise<IResponse> => {
|
export const getDictTypeOptionsApi = (): Promise<IResponse> => {
|
||||||
return request.get({ url: `/vadmin/system/dict/types/options/` })
|
return request.get({ url: `/vadmin/system/dict/types/options` })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getDictTypeDetailsApi = (data: any): Promise<IResponse> => {
|
export const getDictTypeDetailsApi = (data: any): Promise<IResponse> => {
|
||||||
return request.post({ url: `/vadmin/system/dict/types/details/`, data })
|
return request.post({ url: `/vadmin/system/dict/types/details`, data })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getDictDetailsListApi = (params: any): Promise<IResponse> => {
|
export const getDictDetailsListApi = (params: any): Promise<IResponse> => {
|
||||||
return request.get({ url: '/vadmin/system/dict/details/', params })
|
return request.get({ url: '/vadmin/system/dict/details', params })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const addDictDetailsListApi = (data: any): Promise<IResponse> => {
|
export const addDictDetailsListApi = (data: any): Promise<IResponse> => {
|
||||||
return request.post({ url: '/vadmin/system/dict/details/', data })
|
return request.post({ url: '/vadmin/system/dict/details', data })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const delDictDetailsListApi = (data: any): Promise<IResponse> => {
|
export const delDictDetailsListApi = (data: any): Promise<IResponse> => {
|
||||||
return request.delete({ url: '/vadmin/system/dict/details/', data })
|
return request.delete({ url: '/vadmin/system/dict/details', data })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const putDictDetailsListApi = (data: any): Promise<IResponse> => {
|
export const putDictDetailsListApi = (data: any): Promise<IResponse> => {
|
||||||
return request.put({ url: `/vadmin/system/dict/details/${data.id}/`, data })
|
return request.put({ url: `/vadmin/system/dict/details/${data.id}`, data })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getDictDetailsApi = (dataId: number): Promise<IResponse> => {
|
export const getDictDetailsApi = (dataId: number): Promise<IResponse> => {
|
||||||
return request.get({ url: `/vadmin/system/dict/details/${dataId}/` })
|
return request.get({ url: `/vadmin/system/dict/details/${dataId}` })
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ import request from '@/config/axios'
|
|||||||
|
|
||||||
export const addFilesListApi = (data: any): Promise<IResponse> => {
|
export const addFilesListApi = (data: any): Promise<IResponse> => {
|
||||||
return request.post({
|
return request.post({
|
||||||
url: `/vadmin/system/files/`,
|
url: `/vadmin/system/files`,
|
||||||
headersType: 'multipart/form-data',
|
headersType: 'multipart/form-data',
|
||||||
data
|
data
|
||||||
})
|
})
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import request from '@/config/axios'
|
import request from '@/config/axios'
|
||||||
|
|
||||||
export const getRecordLoginListApi = (params: any): Promise<IResponse> => {
|
export const getRecordLoginListApi = (params: any): Promise<IResponse> => {
|
||||||
return request.get({ url: '/vadmin/record/logins/', params })
|
return request.get({ url: '/vadmin/record/logins', params })
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import request from '@/config/axios'
|
import request from '@/config/axios'
|
||||||
|
|
||||||
export const getRecordOperationListApi = (params: any): Promise<IResponse> => {
|
export const getRecordOperationListApi = (params: any): Promise<IResponse> => {
|
||||||
return request.get({ url: '/vadmin/record/operations/', params })
|
return request.get({ url: '/vadmin/record/operations', params })
|
||||||
}
|
}
|
||||||
|
@ -1,28 +1,28 @@
|
|||||||
import request from '@/config/axios'
|
import request from '@/config/axios'
|
||||||
|
|
||||||
export const getSystemSettingsTabsApi = (params: any): Promise<IResponse> => {
|
export const getSystemSettingsTabsApi = (params: any): Promise<IResponse> => {
|
||||||
return request.get({ url: '/vadmin/system/settings/tabs/', params })
|
return request.get({ url: '/vadmin/system/settings/tabs', params })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getSystemSettingsApi = (params: any): Promise<IResponse> => {
|
export const getSystemSettingsApi = (params: any): Promise<IResponse> => {
|
||||||
return request.get({ url: '/vadmin/system/settings/tabs/values/', params })
|
return request.get({ url: '/vadmin/system/settings/tabs/values', params })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const putSystemSettingsApi = (data: any): Promise<IResponse> => {
|
export const putSystemSettingsApi = (data: any): Promise<IResponse> => {
|
||||||
return request.put({ url: '/vadmin/system/settings/tabs/values/', data })
|
return request.put({ url: '/vadmin/system/settings/tabs/values', data })
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取系统基础配置,每次进入系统时使用
|
// 获取系统基础配置,每次进入系统时使用
|
||||||
export const getSystemBaseConfigApi = (): Promise<IResponse> => {
|
export const getSystemBaseConfigApi = (): Promise<IResponse> => {
|
||||||
return request.get({ url: '/vadmin/system/settings/base/config/' })
|
return request.get({ url: '/vadmin/system/settings/base/config' })
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取系统隐私协议
|
// 获取系统隐私协议
|
||||||
export const getSystemPrivacyApi = (): Promise<IResponse> => {
|
export const getSystemPrivacyApi = (): Promise<IResponse> => {
|
||||||
return request.get({ url: '/vadmin/system/settings/privacy/' })
|
return request.get({ url: '/vadmin/system/settings/privacy' })
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取系统用户协议
|
// 获取系统用户协议
|
||||||
export const getSystemAgreementApi = (): Promise<IResponse> => {
|
export const getSystemAgreementApi = (): Promise<IResponse> => {
|
||||||
return request.get({ url: '/vadmin/system/settings/agreement/' })
|
return request.get({ url: '/vadmin/system/settings/agreement' })
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
import { ElBreadcrumb, ElBreadcrumbItem } from 'element-plus'
|
import { ElBreadcrumb, ElBreadcrumbItem } from 'element-plus'
|
||||||
import { ref, watch, computed, unref, defineComponent, TransitionGroup } from 'vue'
|
import { ref, watch, computed, unref, defineComponent, TransitionGroup } from 'vue'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import { usePermissionStore } from '@/store/modules/permission'
|
import { useRouterStore } from '@/store/modules/router'
|
||||||
import { filterBreadcrumb } from './helper'
|
import { filterBreadcrumb } from './helper'
|
||||||
import { filter, treeToList } from '@/utils/tree'
|
import { filter, treeToList } from '@/utils/tree'
|
||||||
import type { RouteLocationNormalizedLoaded, RouteMeta } from 'vue-router'
|
import type { RouteLocationNormalizedLoaded, RouteMeta } from 'vue-router'
|
||||||
@ -29,10 +29,10 @@ export default defineComponent({
|
|||||||
|
|
||||||
const levelList = ref<AppRouteRecordRaw[]>([])
|
const levelList = ref<AppRouteRecordRaw[]>([])
|
||||||
|
|
||||||
const permissionStore = usePermissionStore()
|
const routerStore = useRouterStore()
|
||||||
|
|
||||||
const menuRouters = computed(() => {
|
const menuRouters = computed(() => {
|
||||||
const routers = permissionStore.getRouters
|
const routers = routerStore.getRouters
|
||||||
return filterBreadcrumb(routers)
|
return filterBreadcrumb(routers)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
import { computed, defineComponent, unref, PropType } from 'vue'
|
import { computed, defineComponent, unref, PropType } from 'vue'
|
||||||
import { ElMenu, ElScrollbar } from 'element-plus'
|
import { ElMenu, ElScrollbar } from 'element-plus'
|
||||||
import { useAppStore } from '@/store/modules/app'
|
import { useAppStore } from '@/store/modules/app'
|
||||||
import { usePermissionStore } from '@/store/modules/permission'
|
import { useRouterStore } from '@/store/modules/router'
|
||||||
import { useRenderMenuItem } from './components/useRenderMenuItem'
|
import { useRenderMenuItem } from './components/useRenderMenuItem'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import { isUrl } from '@/utils/is'
|
import { isUrl } from '@/utils/is'
|
||||||
@ -28,7 +28,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
const { push, currentRoute } = useRouter()
|
const { push, currentRoute } = useRouter()
|
||||||
|
|
||||||
const permissionStore = usePermissionStore()
|
const routerStore = useRouterStore()
|
||||||
|
|
||||||
const menuMode = computed((): 'vertical' | 'horizontal' => {
|
const menuMode = computed((): 'vertical' | 'horizontal' => {
|
||||||
// 竖
|
// 竖
|
||||||
@ -42,7 +42,7 @@ export default defineComponent({
|
|||||||
})
|
})
|
||||||
|
|
||||||
const routers = computed(() =>
|
const routers = computed(() =>
|
||||||
unref(layout) === 'cutMenu' ? permissionStore.getMenuTabRouters : permissionStore.getRouters
|
unref(layout) === 'cutMenu' ? routerStore.getMenuTabRouters : routerStore.getRouters
|
||||||
)
|
)
|
||||||
|
|
||||||
const collapse = computed(() => appStore.getCollapse)
|
const collapse = computed(() => appStore.getCollapse)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<script lang="tsx">
|
<script lang="tsx">
|
||||||
import { usePermissionStore } from '@/store/modules/permission'
|
import { useRouterStore } from '@/store/modules/router'
|
||||||
import { useAppStore } from '@/store/modules/app'
|
import { useAppStore } from '@/store/modules/app'
|
||||||
import { computed, unref, defineComponent, watch, ref, onMounted } from 'vue'
|
import { computed, unref, defineComponent, watch, ref, onMounted } from 'vue'
|
||||||
import { useI18n } from '@/hooks/web/useI18n'
|
import { useI18n } from '@/hooks/web/useI18n'
|
||||||
@ -30,9 +30,9 @@ export default defineComponent({
|
|||||||
|
|
||||||
const fixedMenu = computed(() => appStore.getFixedMenu)
|
const fixedMenu = computed(() => appStore.getFixedMenu)
|
||||||
|
|
||||||
const permissionStore = usePermissionStore()
|
const routerStore = useRouterStore()
|
||||||
|
|
||||||
const routers = computed(() => permissionStore.getRouters)
|
const routers = computed(() => routerStore.getRouters)
|
||||||
|
|
||||||
const tabRouters = computed(() => unref(routers).filter((v) => !v?.meta?.hidden))
|
const tabRouters = computed(() => unref(routers).filter((v) => !v?.meta?.hidden))
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
tabActive.value = path
|
tabActive.value = path
|
||||||
if (children) {
|
if (children) {
|
||||||
permissionStore.setMenuTabRouters(
|
routerStore.setMenuTabRouters(
|
||||||
cloneDeep(children).map((v) => {
|
cloneDeep(children).map((v) => {
|
||||||
v.path = pathResolve(unref(tabActive), v.path)
|
v.path = pathResolve(unref(tabActive), v.path)
|
||||||
return v
|
return v
|
||||||
@ -108,7 +108,7 @@ export default defineComponent({
|
|||||||
showMenu.value = unref(fixedMenu) ? true : !unref(showMenu)
|
showMenu.value = unref(fixedMenu) ? true : !unref(showMenu)
|
||||||
}
|
}
|
||||||
if (unref(showMenu)) {
|
if (unref(showMenu)) {
|
||||||
permissionStore.setMenuTabRouters(
|
routerStore.setMenuTabRouters(
|
||||||
cloneDeep(item.children).map((v) => {
|
cloneDeep(item.children).map((v) => {
|
||||||
v.path = pathResolve(unref(tabActive), v.path)
|
v.path = pathResolve(unref(tabActive), v.path)
|
||||||
return v
|
return v
|
||||||
@ -117,7 +117,7 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
push(item.path)
|
push(item.path)
|
||||||
permissionStore.setMenuTabRouters([])
|
routerStore.setMenuTabRouters([])
|
||||||
showMenu.value = false
|
showMenu.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
import { onMounted, watch, computed, unref, ref, nextTick } from 'vue'
|
import { onMounted, watch, computed, unref, ref, nextTick } from 'vue'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import type { RouteLocationNormalizedLoaded, RouterLinkProps } from 'vue-router'
|
import type { RouteLocationNormalizedLoaded, RouterLinkProps } from 'vue-router'
|
||||||
import { usePermissionStore } from '@/store/modules/permission'
|
import { useRouterStore } from '@/store/modules/router'
|
||||||
import { useTagsViewStore } from '@/store/modules/tagsView'
|
import { useTagsViewStore } from '@/store/modules/tagsView'
|
||||||
import { useAppStore } from '@/store/modules/app'
|
import { useAppStore } from '@/store/modules/app'
|
||||||
import { useI18n } from '@/hooks/web/useI18n'
|
import { useI18n } from '@/hooks/web/useI18n'
|
||||||
@ -21,9 +21,9 @@ const { t } = useI18n()
|
|||||||
|
|
||||||
const { currentRoute, push, replace } = useRouter()
|
const { currentRoute, push, replace } = useRouter()
|
||||||
|
|
||||||
const permissionStore = usePermissionStore()
|
const routerStore = useRouterStore()
|
||||||
|
|
||||||
const routers = computed(() => permissionStore.getRouters)
|
const routers = computed(() => routerStore.getRouters)
|
||||||
|
|
||||||
const tagsViewStore = useTagsViewStore()
|
const tagsViewStore = useTagsViewStore()
|
||||||
|
|
||||||
@ -108,14 +108,14 @@ const toLastView = () => {
|
|||||||
push(latestView)
|
push(latestView)
|
||||||
} else {
|
} else {
|
||||||
if (
|
if (
|
||||||
unref(currentRoute).path === permissionStore.getAddRouters[0].path ||
|
unref(currentRoute).path === routerStore.getAddRouters[0].path ||
|
||||||
unref(currentRoute).path === permissionStore.getAddRouters[0].redirect
|
unref(currentRoute).path === routerStore.getAddRouters[0].redirect
|
||||||
) {
|
) {
|
||||||
addTags()
|
addTags()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// You can set another route
|
// You can set another route
|
||||||
push(permissionStore.getAddRouters[0].path)
|
push(routerStore.getAddRouters[0].path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,6 +105,7 @@ service.interceptors.response.use(
|
|||||||
},
|
},
|
||||||
(error: AxiosError) => {
|
(error: AxiosError) => {
|
||||||
let { message } = error
|
let { message } = error
|
||||||
|
const authStore = useAuthStore()
|
||||||
const status = error.response?.status
|
const status = error.response?.status
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case 400:
|
case 400:
|
||||||
@ -112,12 +113,13 @@ service.interceptors.response.use(
|
|||||||
break
|
break
|
||||||
case 401:
|
case 401:
|
||||||
// 强制要求重新登录,因账号已冻结,账号已过期,手机号码错误,刷新token无效等问题导致
|
// 强制要求重新登录,因账号已冻结,账号已过期,手机号码错误,刷新token无效等问题导致
|
||||||
const authStore = useAuthStore()
|
|
||||||
authStore.logout()
|
authStore.logout()
|
||||||
message = '认证已过期,请重新登录'
|
message = '认证已过期,请重新登录'
|
||||||
break
|
break
|
||||||
case 403:
|
case 403:
|
||||||
message = '拒绝访问'
|
// 强制要求重新登录,因无系统权限,而进入到系统访问等问题导致
|
||||||
|
authStore.logout()
|
||||||
|
message = '无权限访问,请联系管理员'
|
||||||
break
|
break
|
||||||
case 404:
|
case 404:
|
||||||
message = `请求地址出错: ${error.response?.config.url}`
|
message = `请求地址出错: ${error.response?.config.url}`
|
||||||
|
@ -1,18 +1,16 @@
|
|||||||
import type { App, Directive, DirectiveBinding } from 'vue'
|
import type { App, Directive, DirectiveBinding } from 'vue'
|
||||||
import { useI18n } from '@/hooks/web/useI18n'
|
import { useI18n } from '@/hooks/web/useI18n'
|
||||||
import { useCache } from '@/hooks/web/useCache'
|
|
||||||
import { intersection } from 'lodash-es'
|
import { intersection } from 'lodash-es'
|
||||||
import { isArray } from '@/utils/is'
|
import { isArray } from '@/utils/is'
|
||||||
import { useAppStoreWithOut } from '@/store/modules/app'
|
import { useAuthStoreWithOut } from '@/store/modules/auth'
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
const { wsCache } = useCache()
|
const authStore = useAuthStoreWithOut()
|
||||||
const appStore = useAppStoreWithOut()
|
|
||||||
|
|
||||||
// 全部权限
|
// 全部权限
|
||||||
const all_permission = ['*.*.*']
|
const all_permission = ['*.*.*']
|
||||||
const hasPermission = (value: string | string[]): boolean => {
|
const hasPermission = (value: string | string[]): boolean => {
|
||||||
const permissions = wsCache.get(appStore.getUserInfo).permissions as string[]
|
const permissions = authStore.getPermissions
|
||||||
if (!value) {
|
if (!value) {
|
||||||
throw new Error(t('permission.hasPermission'))
|
throw new Error(t('permission.hasPermission'))
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import { get } from 'lodash-es'
|
|||||||
import type { TableProps } from '@/components/Table/src/types'
|
import type { TableProps } from '@/components/Table/src/types'
|
||||||
import { useI18n } from '@/hooks/web/useI18n'
|
import { useI18n } from '@/hooks/web/useI18n'
|
||||||
import { TableSetPropsType } from '@/types/table'
|
import { TableSetPropsType } from '@/types/table'
|
||||||
|
import { isEmpty } from '@/utils/is'
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
|
|
||||||
@ -34,7 +35,7 @@ interface TableObject<T = any> {
|
|||||||
tableData: T[]
|
tableData: T[]
|
||||||
params: any
|
params: any
|
||||||
loading: boolean
|
loading: boolean
|
||||||
currentRow: Nullable<T>
|
currentRow: Recordable | null
|
||||||
}
|
}
|
||||||
|
|
||||||
type TableOrderChange = {
|
type TableOrderChange = {
|
||||||
@ -111,7 +112,7 @@ export const useTable = <T = any>(config?: UseTableConfig<T>) => {
|
|||||||
return table
|
return table
|
||||||
}
|
}
|
||||||
|
|
||||||
const delData = async (ids: string[] | number[]) => {
|
const delData = async (ids: string[] | number[] | number) => {
|
||||||
if (config?.delListApi) {
|
if (config?.delListApi) {
|
||||||
const res = await config.delListApi(ids)
|
const res = await config.delListApi(ids)
|
||||||
if (res) {
|
if (res) {
|
||||||
@ -166,29 +167,47 @@ export const useTable = <T = any>(config?: UseTableConfig<T>) => {
|
|||||||
methods.getList()
|
methods.getList()
|
||||||
},
|
},
|
||||||
// 删除数据
|
// 删除数据
|
||||||
delListApi: async (ids: string[] | number[], multiple: boolean, message = true) => {
|
// 如果存在 ids,则直接使用 ids 中的值进行删除
|
||||||
|
// 如果不存在 ids,则判断 multiple 的值来进行删除
|
||||||
|
// 如果 multiple 为 true,则说明是多选框,获取多选框中的数据删除
|
||||||
|
// 如果为 false,则说明是点击按钮,则获取当前选择行数据进行删除
|
||||||
|
delListApi: async (
|
||||||
|
multiple: boolean,
|
||||||
|
ids: string[] | number[] | number = [],
|
||||||
|
message = true
|
||||||
|
) => {
|
||||||
const tableRef = await getTable()
|
const tableRef = await getTable()
|
||||||
if (multiple) {
|
let value: string[] | number[] | number = []
|
||||||
if (!tableRef?.selections.length) {
|
if (isEmpty(ids)) {
|
||||||
ElMessage.warning(t('common.delNoData'))
|
if (multiple) {
|
||||||
return
|
if (!tableRef?.selections.length) {
|
||||||
|
ElMessage.warning(t('common.delNoData'))
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
value = tableRef?.selections.map((item) => item.id)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!tableObject.currentRow) {
|
||||||
|
ElMessage.warning(t('common.delNoData'))
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
value = tableObject.currentRow.id
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!tableObject.currentRow) {
|
value = ids
|
||||||
ElMessage.warning(t('common.delNoData'))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message) {
|
if (message) {
|
||||||
ElMessageBox.confirm(t('common.delMessage'), t('common.delWarning'), {
|
ElMessageBox.confirm(t('common.delMessage'), t('common.delWarning'), {
|
||||||
confirmButtonText: t('common.delOk'),
|
confirmButtonText: t('common.delOk'),
|
||||||
cancelButtonText: t('common.delCancel'),
|
cancelButtonText: t('common.delCancel'),
|
||||||
type: 'warning'
|
type: 'warning'
|
||||||
}).then(async () => {
|
}).then(async () => {
|
||||||
await delData(ids)
|
await delData(value)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
await delData(ids)
|
await delData(value)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 导出筛选列表
|
// 导出筛选列表
|
||||||
|
@ -4,12 +4,12 @@ import { useCache } from '@/hooks/web/useCache'
|
|||||||
import type { RouteRecordRaw } from 'vue-router'
|
import type { RouteRecordRaw } from 'vue-router'
|
||||||
import { useTitle } from '@/hooks/web/useTitle'
|
import { useTitle } from '@/hooks/web/useTitle'
|
||||||
import { useNProgress } from '@/hooks/web/useNProgress'
|
import { useNProgress } from '@/hooks/web/useNProgress'
|
||||||
import { usePermissionStoreWithOut } from '@/store/modules/permission'
|
import { useRouterStoreWithOut } from '@/store/modules/router'
|
||||||
import { usePageLoading } from '@/hooks/web/usePageLoading'
|
import { usePageLoading } from '@/hooks/web/usePageLoading'
|
||||||
import { getRoleMenusApi } from '@/api/login'
|
import { getRoleMenusApi } from '@/api/login'
|
||||||
import { useAuthStoreWithOut } from '@/store/modules/auth'
|
import { useAuthStoreWithOut } from '@/store/modules/auth'
|
||||||
|
|
||||||
const permissionStore = usePermissionStoreWithOut()
|
const Routertore = useRouterStoreWithOut()
|
||||||
|
|
||||||
const appStore = useAppStoreWithOut()
|
const appStore = useAppStoreWithOut()
|
||||||
const authStore = useAuthStoreWithOut()
|
const authStore = useAuthStoreWithOut()
|
||||||
@ -25,16 +25,16 @@ const whiteList = ['/login', '/docs/privacy', '/docs/agreement'] // 不重定向
|
|||||||
router.beforeEach(async (to, from, next) => {
|
router.beforeEach(async (to, from, next) => {
|
||||||
start()
|
start()
|
||||||
loadStart()
|
loadStart()
|
||||||
if (wsCache.get(appStore.getUserInfo)) {
|
if (wsCache.get(appStore.getToken)) {
|
||||||
if (to.path === '/login') {
|
if (to.path === '/login') {
|
||||||
next({ path: '/' })
|
next({ path: '/' })
|
||||||
} else if (to.path === '/reset/password') {
|
} else if (to.path === '/reset/password') {
|
||||||
next()
|
next()
|
||||||
} else {
|
} else {
|
||||||
if (!authStore.getIsUser) {
|
if (!authStore.getIsUser) {
|
||||||
await authStore.getUserInfo()
|
await authStore.setUserInfo()
|
||||||
}
|
}
|
||||||
if (permissionStore.getIsAddRouters) {
|
if (Routertore.getIsAddRouters) {
|
||||||
next()
|
next()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -44,14 +44,14 @@ router.beforeEach(async (to, from, next) => {
|
|||||||
const { wsCache } = useCache()
|
const { wsCache } = useCache()
|
||||||
const routers = res.data || []
|
const routers = res.data || []
|
||||||
wsCache.set('roleRouters', routers)
|
wsCache.set('roleRouters', routers)
|
||||||
await permissionStore.generateRoutes(routers).catch(() => {})
|
await Routertore.generateRoutes(routers).catch(() => {})
|
||||||
permissionStore.getAddRouters.forEach((route) => {
|
Routertore.getAddRouters.forEach((route) => {
|
||||||
router.addRoute(route as RouteRecordRaw) // 动态添加可访问路由表
|
router.addRoute(route as RouteRecordRaw) // 动态添加可访问路由表
|
||||||
})
|
})
|
||||||
const redirectPath = from.query.redirect || to.path
|
const redirectPath = from.query.redirect || to.path
|
||||||
const redirect = decodeURIComponent(redirectPath as string)
|
const redirect = decodeURIComponent(redirectPath as string)
|
||||||
const nextData = to.path === redirect ? { ...to, replace: true } : { path: redirect }
|
const nextData = to.path === redirect ? { ...to, replace: true } : { path: redirect }
|
||||||
permissionStore.setIsAddRouters(true)
|
Routertore.setIsAddRouters(true)
|
||||||
next(nextData)
|
next(nextData)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -27,7 +27,6 @@ interface AppState {
|
|||||||
pageLoading: boolean
|
pageLoading: boolean
|
||||||
layout: LayoutType
|
layout: LayoutType
|
||||||
title: string
|
title: string
|
||||||
userInfo: string
|
|
||||||
isDark: boolean
|
isDark: boolean
|
||||||
currentSize: ElementPlusSize
|
currentSize: ElementPlusSize
|
||||||
sizeMap: ElementPlusSize[]
|
sizeMap: ElementPlusSize[]
|
||||||
@ -45,7 +44,6 @@ interface AppState {
|
|||||||
export const useAppStore = defineStore('app', {
|
export const useAppStore = defineStore('app', {
|
||||||
state: (): AppState => {
|
state: (): AppState => {
|
||||||
return {
|
return {
|
||||||
userInfo: 'userInfo', // 登录信息存储字段-建议每个项目换一个字段,避免与其他项目冲突
|
|
||||||
token: 'Token', // 存储Token字段
|
token: 'Token', // 存储Token字段
|
||||||
refreshToken: 'RefreshToken', // 存储刷新Token字段
|
refreshToken: 'RefreshToken', // 存储刷新Token字段
|
||||||
sizeMap: ['default', 'large', 'small'],
|
sizeMap: ['default', 'large', 'small'],
|
||||||
@ -166,9 +164,6 @@ export const useAppStore = defineStore('app', {
|
|||||||
getTitle(): string {
|
getTitle(): string {
|
||||||
return this.title
|
return this.title
|
||||||
},
|
},
|
||||||
getUserInfo(): string {
|
|
||||||
return this.userInfo
|
|
||||||
},
|
|
||||||
getToken(): string {
|
getToken(): string {
|
||||||
return this.token
|
return this.token
|
||||||
},
|
},
|
||||||
|
@ -8,12 +8,14 @@ import { getCurrentAdminUserInfo } from '@/api/vadmin/auth/user'
|
|||||||
import { resetRouter } from '@/router'
|
import { resetRouter } from '@/router'
|
||||||
import { useTagsViewStore } from '@/store/modules/tagsView'
|
import { useTagsViewStore } from '@/store/modules/tagsView'
|
||||||
import router from '@/router'
|
import router from '@/router'
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
|
||||||
const { wsCache } = useCache()
|
const { wsCache } = useCache()
|
||||||
|
|
||||||
export interface UserState {
|
export interface UserState {
|
||||||
id?: number
|
id?: number
|
||||||
telephone?: string
|
telephone?: string
|
||||||
|
email?: string
|
||||||
name?: string
|
name?: string
|
||||||
nickname?: string
|
nickname?: string
|
||||||
avatar?: string
|
avatar?: string
|
||||||
@ -23,14 +25,18 @@ export interface UserState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface AuthState {
|
export interface AuthState {
|
||||||
user: UserState
|
user: UserState // 当前用户基本信息
|
||||||
isUser: boolean
|
isUser: boolean // 是否已经登录并获取到用户信息
|
||||||
|
roles: string[] // 当前用户角色 role_key 列表
|
||||||
|
permissions: string[] // 当前用户权限列表
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useAuthStore = defineStore('auth', {
|
export const useAuthStore = defineStore('auth', {
|
||||||
state: (): AuthState => {
|
state: (): AuthState => {
|
||||||
return {
|
return {
|
||||||
user: {},
|
user: {},
|
||||||
|
roles: [],
|
||||||
|
permissions: [],
|
||||||
isUser: false
|
isUser: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -38,6 +44,12 @@ export const useAuthStore = defineStore('auth', {
|
|||||||
getUser(): UserState {
|
getUser(): UserState {
|
||||||
return this.user
|
return this.user
|
||||||
},
|
},
|
||||||
|
getRoles(): string[] {
|
||||||
|
return this.roles
|
||||||
|
},
|
||||||
|
getPermissions(): string[] {
|
||||||
|
return this.permissions
|
||||||
|
},
|
||||||
getIsUser(): boolean {
|
getIsUser(): boolean {
|
||||||
return this.isUser
|
return this.isUser
|
||||||
}
|
}
|
||||||
@ -50,35 +62,45 @@ export const useAuthStore = defineStore('auth', {
|
|||||||
const appStore = useAppStore()
|
const appStore = useAppStore()
|
||||||
wsCache.set(appStore.getToken, `${res.data.token_type} ${res.data.access_token}`)
|
wsCache.set(appStore.getToken, `${res.data.token_type} ${res.data.access_token}`)
|
||||||
wsCache.set(appStore.getRefreshToken, res.data.refresh_token)
|
wsCache.set(appStore.getRefreshToken, res.data.refresh_token)
|
||||||
// 存储用户信息
|
// 获取当前登录用户的信息
|
||||||
const auth = useAuthStore()
|
await this.setUserInfo()
|
||||||
await auth.getUserInfo()
|
|
||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
},
|
},
|
||||||
logout() {
|
logout(message?: string) {
|
||||||
wsCache.clear()
|
wsCache.clear()
|
||||||
this.user = {}
|
this.user = {}
|
||||||
|
this.roles = []
|
||||||
|
this.permissions = []
|
||||||
this.isUser = false
|
this.isUser = false
|
||||||
const tagsViewStore = useTagsViewStore()
|
const tagsViewStore = useTagsViewStore()
|
||||||
tagsViewStore.delAllViews()
|
tagsViewStore.delAllViews()
|
||||||
resetRouter()
|
resetRouter()
|
||||||
router.push('/login')
|
router.push('/login')
|
||||||
|
if (message) {
|
||||||
|
ElMessage.error(message)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
// 这里更新用户是自己在个人中心更新自己的用户信息,不包括在用户列表中更新的,所以不包含权限角色等信息
|
||||||
|
// 用户信息取消使用持久化存储,仅使用共享存储
|
||||||
updateUser(data: UserState) {
|
updateUser(data: UserState) {
|
||||||
this.user.gender = data.gender
|
this.user.gender = data.gender
|
||||||
this.user.name = data.name
|
this.user.name = data.name
|
||||||
this.user.nickname = data.nickname
|
this.user.nickname = data.nickname
|
||||||
this.user.telephone = data.telephone
|
this.user.telephone = data.telephone
|
||||||
const appStore = useAppStore()
|
|
||||||
wsCache.set(appStore.getUserInfo, this.user)
|
|
||||||
},
|
},
|
||||||
async getUserInfo() {
|
// 获取用户详细信息,包括角色,权限
|
||||||
|
// 用户信息取消使用持久化存储,仅使用共享存储
|
||||||
|
async setUserInfo() {
|
||||||
const res = await getCurrentAdminUserInfo()
|
const res = await getCurrentAdminUserInfo()
|
||||||
const appStore = useAppStore()
|
|
||||||
wsCache.set(appStore.getUserInfo, res.data)
|
|
||||||
this.isUser = true
|
this.isUser = true
|
||||||
this.user = res.data
|
this.user = res.data
|
||||||
|
this.roles = res.data.roles.map((item) => {
|
||||||
|
if (!item.disabled) {
|
||||||
|
return item.role_key
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.permissions = res.data.permissions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -4,15 +4,15 @@ import { generateRoutesFn2, flatMultiLevelRoutes } from '@/utils/routerHelper'
|
|||||||
import { store } from '../index'
|
import { store } from '../index'
|
||||||
import { cloneDeep } from 'lodash-es'
|
import { cloneDeep } from 'lodash-es'
|
||||||
|
|
||||||
export interface PermissionState {
|
export interface RouterState {
|
||||||
routers: AppRouteRecordRaw[]
|
routers: AppRouteRecordRaw[]
|
||||||
addRouters: AppRouteRecordRaw[]
|
addRouters: AppRouteRecordRaw[]
|
||||||
isAddRouters: boolean
|
isAddRouters: boolean
|
||||||
menuTabRouters: AppRouteRecordRaw[]
|
menuTabRouters: AppRouteRecordRaw[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export const usePermissionStore = defineStore('permission', {
|
export const useRouterStore = defineStore('router', {
|
||||||
state: (): PermissionState => ({
|
state: (): RouterState => ({
|
||||||
routers: [],
|
routers: [],
|
||||||
addRouters: [],
|
addRouters: [],
|
||||||
isAddRouters: false,
|
isAddRouters: false,
|
||||||
@ -63,6 +63,6 @@ export const usePermissionStore = defineStore('permission', {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
export const usePermissionStoreWithOut = () => {
|
export const useRouterStoreWithOut = () => {
|
||||||
return usePermissionStore(store)
|
return useRouterStore(store)
|
||||||
}
|
}
|
@ -2,7 +2,7 @@
|
|||||||
import { useTimeAgo } from '@/hooks/web/useTimeAgo'
|
import { useTimeAgo } from '@/hooks/web/useTimeAgo'
|
||||||
import { ElRow, ElCol, ElSkeleton, ElCard, ElDivider, ElLink } from 'element-plus'
|
import { ElRow, ElCol, ElSkeleton, ElCard, ElDivider, ElLink } from 'element-plus'
|
||||||
import { useI18n } from '@/hooks/web/useI18n'
|
import { useI18n } from '@/hooks/web/useI18n'
|
||||||
import { ref, reactive } from 'vue'
|
import { ref, reactive, computed } from 'vue'
|
||||||
import { CountTo } from '@/components/CountTo'
|
import { CountTo } from '@/components/CountTo'
|
||||||
import { formatTime } from '@/utils'
|
import { formatTime } from '@/utils'
|
||||||
import { Highlight } from '@/components/Highlight'
|
import { Highlight } from '@/components/Highlight'
|
||||||
@ -20,11 +20,10 @@ import type {
|
|||||||
Team,
|
Team,
|
||||||
Shortcuts
|
Shortcuts
|
||||||
} from '@/api/dashboard/workplace/types'
|
} from '@/api/dashboard/workplace/types'
|
||||||
import { useCache } from '@/hooks/web/useCache'
|
|
||||||
import { useAppStoreWithOut } from '@/store/modules/app'
|
|
||||||
import avatar from '@/assets/imgs/avatar.jpg'
|
import avatar from '@/assets/imgs/avatar.jpg'
|
||||||
|
import { useAuthStoreWithOut } from '@/store/modules/auth'
|
||||||
|
|
||||||
const { wsCache } = useCache()
|
const authStore = useAuthStoreWithOut()
|
||||||
|
|
||||||
const loading = ref(true)
|
const loading = ref(true)
|
||||||
|
|
||||||
@ -97,9 +96,7 @@ getAllApi()
|
|||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
|
|
||||||
const appStore = useAppStoreWithOut()
|
const user = computed(() => authStore.getUser)
|
||||||
|
|
||||||
const user = wsCache.get(appStore.getUserInfo)
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -6,7 +6,7 @@ import { ElButton, ElCheckbox, ElLink } from 'element-plus'
|
|||||||
import { useForm } from '@/hooks/web/useForm'
|
import { useForm } from '@/hooks/web/useForm'
|
||||||
import { getRoleMenusApi } from '@/api/login'
|
import { getRoleMenusApi } from '@/api/login'
|
||||||
import { useAuthStoreWithOut } from '@/store/modules/auth'
|
import { useAuthStoreWithOut } from '@/store/modules/auth'
|
||||||
import { usePermissionStore } from '@/store/modules/permission'
|
import { useRouterStore } from '@/store/modules/router'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import type { RouteLocationNormalizedLoaded, RouteRecordRaw } from 'vue-router'
|
import type { RouteLocationNormalizedLoaded, RouteRecordRaw } from 'vue-router'
|
||||||
import { UserLoginType } from '@/api/login/types'
|
import { UserLoginType } from '@/api/login/types'
|
||||||
@ -18,7 +18,7 @@ const emit = defineEmits(['to-telephone-code'])
|
|||||||
|
|
||||||
const { required } = useValidator()
|
const { required } = useValidator()
|
||||||
|
|
||||||
const permissionStore = usePermissionStore()
|
const routerStore = useRouterStore()
|
||||||
|
|
||||||
const { currentRoute, addRoute, push } = useRouter()
|
const { currentRoute, addRoute, push } = useRouter()
|
||||||
|
|
||||||
@ -157,12 +157,12 @@ const getMenu = async () => {
|
|||||||
const { wsCache } = useCache()
|
const { wsCache } = useCache()
|
||||||
const routers = res.data || []
|
const routers = res.data || []
|
||||||
wsCache.set('roleRouters', routers)
|
wsCache.set('roleRouters', routers)
|
||||||
await permissionStore.generateRoutes(routers).catch(() => {})
|
await routerStore.generateRoutes(routers).catch(() => {})
|
||||||
permissionStore.getAddRouters.forEach((route) => {
|
routerStore.getAddRouters.forEach((route) => {
|
||||||
addRoute(route as RouteRecordRaw) // 动态添加可访问路由表
|
addRoute(route as RouteRecordRaw) // 动态添加可访问路由表
|
||||||
})
|
})
|
||||||
permissionStore.setIsAddRouters(true)
|
routerStore.setIsAddRouters(true)
|
||||||
push({ path: redirect.value || permissionStore.addRouters[0].path })
|
push({ path: redirect.value || routerStore.addRouters[0].path })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ import { useAuthStoreWithOut } from '@/store/modules/auth'
|
|||||||
import { RouteLocationNormalizedLoaded, useRouter, RouteRecordRaw } from 'vue-router'
|
import { RouteLocationNormalizedLoaded, useRouter, RouteRecordRaw } from 'vue-router'
|
||||||
import { getRoleMenusApi } from '@/api/login'
|
import { getRoleMenusApi } from '@/api/login'
|
||||||
import { useCache } from '@/hooks/web/useCache'
|
import { useCache } from '@/hooks/web/useCache'
|
||||||
import { usePermissionStore } from '@/store/modules/permission'
|
import { useRouterStore } from '@/store/modules/router'
|
||||||
|
|
||||||
const emit = defineEmits(['to-login'])
|
const emit = defineEmits(['to-login'])
|
||||||
|
|
||||||
@ -20,7 +20,7 @@ const { register, elFormRef, methods } = useForm()
|
|||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
const { required } = useValidator()
|
const { required } = useValidator()
|
||||||
const { currentRoute, addRoute, push } = useRouter()
|
const { currentRoute, addRoute, push } = useRouter()
|
||||||
const permissionStore = usePermissionStore()
|
const routerStore = useRouterStore()
|
||||||
|
|
||||||
const schema = reactive<FormSchema[]>([
|
const schema = reactive<FormSchema[]>([
|
||||||
{
|
{
|
||||||
@ -157,12 +157,12 @@ const getMenu = async () => {
|
|||||||
const { wsCache } = useCache()
|
const { wsCache } = useCache()
|
||||||
const routers = res.data || []
|
const routers = res.data || []
|
||||||
wsCache.set('roleRouters', routers)
|
wsCache.set('roleRouters', routers)
|
||||||
await permissionStore.generateRoutes(routers).catch(() => {})
|
await routerStore.generateRoutes(routers).catch(() => {})
|
||||||
permissionStore.getAddRouters.forEach((route) => {
|
routerStore.getAddRouters.forEach((route) => {
|
||||||
addRoute(route as RouteRecordRaw) // 动态添加可访问路由表
|
addRoute(route as RouteRecordRaw) // 动态添加可访问路由表
|
||||||
})
|
})
|
||||||
permissionStore.setIsAddRouters(true)
|
routerStore.setIsAddRouters(true)
|
||||||
push({ path: redirect.value || permissionStore.addRouters[0].path })
|
push({ path: redirect.value || routerStore.addRouters[0].path })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -4,7 +4,7 @@ import { Form } from '@/components/Form'
|
|||||||
import { ElButton } from 'element-plus'
|
import { ElButton } from 'element-plus'
|
||||||
import { useForm } from '@/hooks/web/useForm'
|
import { useForm } from '@/hooks/web/useForm'
|
||||||
import { postCurrentUserResetPassword } from '@/api/vadmin/auth/user'
|
import { postCurrentUserResetPassword } from '@/api/vadmin/auth/user'
|
||||||
import { usePermissionStore } from '@/store/modules/permission'
|
import { useRouterStore } from '@/store/modules/router'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import type { RouteRecordRaw, RouteLocationNormalizedLoaded } from 'vue-router'
|
import type { RouteRecordRaw, RouteLocationNormalizedLoaded } from 'vue-router'
|
||||||
import { getRoleMenusApi } from '@/api/login'
|
import { getRoleMenusApi } from '@/api/login'
|
||||||
@ -21,7 +21,7 @@ const { required } = useValidator()
|
|||||||
|
|
||||||
const footer = computed(() => appStore.getFooter)
|
const footer = computed(() => appStore.getFooter)
|
||||||
|
|
||||||
const permissionStore = usePermissionStore()
|
const routerStore = useRouterStore()
|
||||||
|
|
||||||
const { addRoute, push, currentRoute } = useRouter()
|
const { addRoute, push, currentRoute } = useRouter()
|
||||||
|
|
||||||
@ -124,12 +124,12 @@ const getMenu = async () => {
|
|||||||
const { wsCache } = useCache()
|
const { wsCache } = useCache()
|
||||||
const routers = res.data || []
|
const routers = res.data || []
|
||||||
wsCache.set('roleRouters', routers)
|
wsCache.set('roleRouters', routers)
|
||||||
await permissionStore.generateRoutes(routers).catch(() => {})
|
await routerStore.generateRoutes(routers).catch(() => {})
|
||||||
permissionStore.getAddRouters.forEach((route) => {
|
routerStore.getAddRouters.forEach((route) => {
|
||||||
addRoute(route as RouteRecordRaw) // 动态添加可访问路由表
|
addRoute(route as RouteRecordRaw) // 动态添加可访问路由表
|
||||||
})
|
})
|
||||||
permissionStore.setIsAddRouters(true)
|
routerStore.setIsAddRouters(true)
|
||||||
push({ path: redirect.value || permissionStore.addRouters[0].path })
|
push({ path: redirect.value || routerStore.addRouters[0].path })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -76,7 +76,7 @@ defineExpose({
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Form :rules="rules" @register="register">
|
<Form :rules="rules" @register="register" :labelWidth="100">
|
||||||
<template #icon="form">
|
<template #icon="form">
|
||||||
<div style="display: flex; justify-content: space-between">
|
<div style="display: flex; justify-content: space-between">
|
||||||
<ElInput
|
<ElInput
|
||||||
|
@ -49,7 +49,6 @@ const { register, elTableRef, tableObject, methods } = useTable({
|
|||||||
|
|
||||||
const dialogVisible = ref(false)
|
const dialogVisible = ref(false)
|
||||||
const dialogTitle = ref('')
|
const dialogTitle = ref('')
|
||||||
const delLoading = ref(false)
|
|
||||||
const actionType = ref('')
|
const actionType = ref('')
|
||||||
const parentId = ref()
|
const parentId = ref()
|
||||||
|
|
||||||
@ -74,12 +73,8 @@ const updateAction = (row: any) => {
|
|||||||
// 删除事件
|
// 删除事件
|
||||||
const delData = async (row: any) => {
|
const delData = async (row: any) => {
|
||||||
parentId.value = null
|
parentId.value = null
|
||||||
tableObject.currentRow = row
|
|
||||||
const { delListApi } = methods
|
const { delListApi } = methods
|
||||||
delLoading.value = true
|
await delListApi(true, [row.id])
|
||||||
await delListApi([row.id], false).finally(() => {
|
|
||||||
delLoading.value = false
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加子菜单事件
|
// 添加子菜单事件
|
||||||
|
@ -75,7 +75,7 @@ defineExpose({
|
|||||||
|
|
||||||
let selectAll = ref(false)
|
let selectAll = ref(false)
|
||||||
let defaultExpandAll = ref(true)
|
let defaultExpandAll = ref(true)
|
||||||
let checkStrictly = ref(false)
|
let checkStrictly = ref(true) // 父子联动
|
||||||
|
|
||||||
// 获取所有节点的key
|
// 获取所有节点的key
|
||||||
const getTreeNodeKeys = (nodes: Recordable[]): number[] => {
|
const getTreeNodeKeys = (nodes: Recordable[]): number[] => {
|
||||||
|
@ -65,12 +65,8 @@ const updateAction = async (row: any) => {
|
|||||||
|
|
||||||
// 删除事件
|
// 删除事件
|
||||||
const delData = async (row: any) => {
|
const delData = async (row: any) => {
|
||||||
tableObject.currentRow = row
|
|
||||||
const { delListApi } = methods
|
const { delListApi } = methods
|
||||||
loading.value = true
|
await delListApi(true, [row.id])
|
||||||
await delListApi([row.id], false).finally(() => {
|
|
||||||
loading.value = false
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const writeRef = ref<ComponentRef<typeof Write>>()
|
const writeRef = ref<ComponentRef<typeof Write>>()
|
||||||
|
@ -1,98 +0,0 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
import { ElButton, ElTable, ElTableColumn, ElPopconfirm, ElMessage, ElTag } from 'element-plus'
|
|
||||||
import { postUsersInitPasswordSendSMSApi } from '@/api/vadmin/auth/user'
|
|
||||||
import { ref, PropType } from 'vue'
|
|
||||||
|
|
||||||
const emit = defineEmits(['getList'])
|
|
||||||
|
|
||||||
const props = defineProps({
|
|
||||||
selections: {
|
|
||||||
type: Object as PropType<Recordable[]>
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const tableData = ref(JSON.parse(JSON.stringify(props.selections)))
|
|
||||||
const loading = ref(false)
|
|
||||||
|
|
||||||
const handleDelete = (index: number) => {
|
|
||||||
tableData.value.splice(index, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
const initPassword = async () => {
|
|
||||||
loading.value = true
|
|
||||||
const ids = tableData.value
|
|
||||||
.filter((item) => item.reset_password_status !== true)
|
|
||||||
.map((item) => item.id)
|
|
||||||
if (ids.length <= 0) {
|
|
||||||
return ElMessage.warning('已全部重置完成,无需重复操作')
|
|
||||||
}
|
|
||||||
const res = await postUsersInitPasswordSendSMSApi(ids).finally(() => {
|
|
||||||
loading.value = false
|
|
||||||
})
|
|
||||||
if (res) {
|
|
||||||
tableData.value = res.data
|
|
||||||
ElMessage.success('重置成功')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<div class="flex justify-between">
|
|
||||||
<span>已选用户列表</span>
|
|
||||||
<ElButton
|
|
||||||
type="primary"
|
|
||||||
:disabled="tableData?.length === 0"
|
|
||||||
:loading="loading"
|
|
||||||
@click="initPassword"
|
|
||||||
>确认重置并发送短信通知</ElButton
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
<ElTable
|
|
||||||
:data="tableData"
|
|
||||||
:stripe="true"
|
|
||||||
:border="true"
|
|
||||||
style="width: 100%"
|
|
||||||
class="mt-10px"
|
|
||||||
max-height="500px"
|
|
||||||
>
|
|
||||||
<ElTableColumn prop="id" label="用户编号" width="100" align="center" />
|
|
||||||
<ElTableColumn prop="name" label="姓名" width="120" align="center" />
|
|
||||||
<ElTableColumn prop="telephone" label="手机号" width="120" align="center" />
|
|
||||||
<ElTableColumn prop="reset_password_status" label="重置状态" width="100" align="center">
|
|
||||||
<template #default="scope">
|
|
||||||
<ElTag v-if="scope.row.reset_password_status === true" type="success" effect="dark">
|
|
||||||
重置成功
|
|
||||||
</ElTag>
|
|
||||||
<ElTag v-else-if="scope.row.reset_password_status === false" type="danger" effect="dark">
|
|
||||||
重置失败
|
|
||||||
</ElTag>
|
|
||||||
<ElTag v-else type="warning" effect="dark"> 待重置 </ElTag>
|
|
||||||
</template>
|
|
||||||
</ElTableColumn>
|
|
||||||
<ElTableColumn prop="send_sms_status" label="发送状态" width="100" align="center">
|
|
||||||
<template #default="scope">
|
|
||||||
<ElTag v-if="scope.row.send_sms_status === true" type="success" effect="dark">
|
|
||||||
发送成功
|
|
||||||
</ElTag>
|
|
||||||
<ElTag v-else-if="scope.row.send_sms_status === false" type="danger" effect="dark">
|
|
||||||
发送失败
|
|
||||||
</ElTag>
|
|
||||||
<ElTag v-else type="warning" effect="dark"> 待发送 </ElTag>
|
|
||||||
</template>
|
|
||||||
</ElTableColumn>
|
|
||||||
<ElTableColumn prop="send_sms_msg" label="描述" align="center" />
|
|
||||||
<ElTableColumn fixed="right" label="操作" width="100" align="center">
|
|
||||||
<template #default="scope">
|
|
||||||
<ElPopconfirm title="确认移除吗?" @confirm="handleDelete(scope.$index)">
|
|
||||||
<template #reference>
|
|
||||||
<ElButton v-if="scope.row.send_sms_status !== true" link type="primary" size="small"
|
|
||||||
>移除</ElButton
|
|
||||||
>
|
|
||||||
</template>
|
|
||||||
</ElPopconfirm>
|
|
||||||
</template>
|
|
||||||
</ElTableColumn>
|
|
||||||
</ElTable>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
@ -71,6 +71,9 @@ const { register, elTableRef, tableObject, methods } = useTable({
|
|||||||
},
|
},
|
||||||
defaultParams: {
|
defaultParams: {
|
||||||
is_active: true
|
is_active: true
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
columns
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -100,20 +103,16 @@ const updateAction = async (row: any) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 删除事件
|
// 删除事件
|
||||||
const delDatas = async (row: any, multiple: boolean) => {
|
const delDatas = async (row: any) => {
|
||||||
const { delListApi, getSelections } = methods
|
const { delListApi, getSelections } = methods
|
||||||
loading.value = true
|
|
||||||
const selections = ref([] as any[])
|
const selections = ref([] as any[])
|
||||||
if (multiple) {
|
if (row) {
|
||||||
|
selections.value = [row.id]
|
||||||
|
} else {
|
||||||
selections.value = await getSelections()
|
selections.value = await getSelections()
|
||||||
selections.value = selections.value.map((item) => item.id)
|
selections.value = selections.value.map((item) => item.id)
|
||||||
} else {
|
|
||||||
tableObject.currentRow = row
|
|
||||||
selections.value = [row.id]
|
|
||||||
}
|
}
|
||||||
await delListApi(selections.value, multiple).finally(() => {
|
await delListApi(true, selections.value)
|
||||||
loading.value = false
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const writeRef = ref<ComponentRef<typeof Write>>()
|
const writeRef = ref<ComponentRef<typeof Write>>()
|
||||||
@ -224,7 +223,7 @@ const handleCommand = (command: string) => {
|
|||||||
} else if (command === 'd') {
|
} else if (command === 'd') {
|
||||||
sendPasswordToEmail()
|
sendPasswordToEmail()
|
||||||
} else if (command === 'e') {
|
} else if (command === 'e') {
|
||||||
delDatas(null, true)
|
delDatas(null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@ -256,7 +255,7 @@ const handleCommand = (command: string) => {
|
|||||||
<ElButton @click="sendPasswordToEmail">重置密码通知邮件</ElButton>
|
<ElButton @click="sendPasswordToEmail">重置密码通知邮件</ElButton>
|
||||||
</ElCol>
|
</ElCol>
|
||||||
<ElCol :span="1.5" v-hasPermi="['auth.user.delete']" v-if="!mobile">
|
<ElCol :span="1.5" v-hasPermi="['auth.user.delete']" v-if="!mobile">
|
||||||
<ElButton type="danger" @click="delDatas(null, true)">批量删除</ElButton>
|
<ElButton type="danger" @click="delDatas(null)">批量删除</ElButton>
|
||||||
</ElCol>
|
</ElCol>
|
||||||
<ElCol :span="1.5" v-if="mobile">
|
<ElCol :span="1.5" v-if="mobile">
|
||||||
<ElDropdown trigger="click" @command="handleCommand">
|
<ElDropdown trigger="click" @command="handleCommand">
|
||||||
@ -325,7 +324,7 @@ const handleCommand = (command: string) => {
|
|||||||
v-hasPermi="['auth.user.delete']"
|
v-hasPermi="['auth.user.delete']"
|
||||||
link
|
link
|
||||||
size="small"
|
size="small"
|
||||||
@click="delDatas(row, false)"
|
@click="delDatas(row)"
|
||||||
v-if="authStore.getUser.id !== row.id && row.id !== 1"
|
v-if="authStore.getUser.id !== row.id && row.id !== 1"
|
||||||
>
|
>
|
||||||
{{ t('exampleDemo.del') }}
|
{{ t('exampleDemo.del') }}
|
||||||
|
@ -58,7 +58,6 @@ watch(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
const loading = ref(false)
|
|
||||||
const searchSetSchemaList = ref([] as FormSetPropsType[])
|
const searchSetSchemaList = ref([] as FormSetPropsType[])
|
||||||
|
|
||||||
const getOptions = async () => {
|
const getOptions = async () => {
|
||||||
@ -84,12 +83,8 @@ const updateAction = async (row: any) => {
|
|||||||
|
|
||||||
// 删除事件
|
// 删除事件
|
||||||
const delData = async (row: any) => {
|
const delData = async (row: any) => {
|
||||||
tableObject.currentRow = row
|
|
||||||
const { delListApi } = methods
|
const { delListApi } = methods
|
||||||
loading.value = true
|
await delListApi(true, [row.id])
|
||||||
await delListApi([row.id], false).finally(() => {
|
|
||||||
loading.value = false
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getList()
|
getList()
|
||||||
|
@ -103,12 +103,8 @@ const updateAction = async (row: any) => {
|
|||||||
|
|
||||||
// 删除事件
|
// 删除事件
|
||||||
const delData = async (row: any) => {
|
const delData = async (row: any) => {
|
||||||
tableObject.currentRow = row
|
|
||||||
const { delListApi } = methods
|
const { delListApi } = methods
|
||||||
loading.value = true
|
await delListApi(true, [row.id])
|
||||||
await delListApi([row.id], false).finally(() => {
|
|
||||||
loading.value = false
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const writeRef = ref<ComponentRef<typeof Write>>()
|
const writeRef = ref<ComponentRef<typeof Write>>()
|
||||||
|
@ -89,12 +89,8 @@ const updateAction = async (row: any) => {
|
|||||||
|
|
||||||
// 删除事件
|
// 删除事件
|
||||||
const delData = async (row: any) => {
|
const delData = async (row: any) => {
|
||||||
tableObject.currentRow = row
|
|
||||||
const { delListApi } = methods
|
const { delListApi } = methods
|
||||||
loading.value = true
|
await delListApi(true, [row.id])
|
||||||
await delListApi([row.id], false).finally(() => {
|
|
||||||
loading.value = false
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const writeRef = ref<ComponentRef<typeof Write>>()
|
const writeRef = ref<ComponentRef<typeof Write>>()
|
||||||
|
@ -64,12 +64,8 @@ const updateAction = async (row: any) => {
|
|||||||
|
|
||||||
// 删除事件
|
// 删除事件
|
||||||
const delData = async (row: any) => {
|
const delData = async (row: any) => {
|
||||||
tableObject.currentRow = row
|
|
||||||
const { delListApi } = methods
|
const { delListApi } = methods
|
||||||
loading.value = true
|
await delListApi(true, [row.id])
|
||||||
await delListApi([row.id], false).finally(() => {
|
|
||||||
loading.value = false
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 跳转到字典详情页面
|
// 跳转到字典详情页面
|
||||||
|
@ -83,7 +83,7 @@ python main.py init
|
|||||||
python main.py run
|
python main.py run
|
||||||
```
|
```
|
||||||
|
|
||||||
## 其他
|
## 其他操作
|
||||||
|
|
||||||
在线文档地址(在配置文件里面设置路径或者关闭)
|
在线文档地址(在配置文件里面设置路径或者关闭)
|
||||||
|
|
||||||
@ -92,6 +92,7 @@ http://127.0.0.1:9000/docs
|
|||||||
```
|
```
|
||||||
|
|
||||||
Git更新ignore文件直接修改gitignore是不会生效的,需要先去掉已经托管的文件,修改完成之后再重新添加并提交。
|
Git更新ignore文件直接修改gitignore是不会生效的,需要先去掉已经托管的文件,修改完成之后再重新添加并提交。
|
||||||
|
|
||||||
```
|
```
|
||||||
第一步:
|
第一步:
|
||||||
git rm -r --cached .
|
git rm -r --cached .
|
||||||
@ -115,4 +116,173 @@ python main.py migrate
|
|||||||
python main.py migrate --env dev
|
python main.py migrate --env dev
|
||||||
```
|
```
|
||||||
|
|
||||||
生成迁移文件后,会在alembic迁移目录中的version目录中多个迁移文件
|
生成迁移文件后,会在alembic迁移目录中的version目录中多个迁移文件
|
||||||
|
|
||||||
|
## 查询数据
|
||||||
|
|
||||||
|
### 查询过滤
|
||||||
|
|
||||||
|
```python
|
||||||
|
# 日期查询
|
||||||
|
# 值的类型:str
|
||||||
|
# 值得格式:%Y-%m-%d:2023-05-14
|
||||||
|
字段名称=("date", 值)
|
||||||
|
|
||||||
|
# 模糊查询
|
||||||
|
# 值的类型: str
|
||||||
|
字段名称=("like", 值)
|
||||||
|
|
||||||
|
# in 查询
|
||||||
|
# 值的类型:list
|
||||||
|
字段名称=("in", 值)
|
||||||
|
|
||||||
|
# 时间区间查询
|
||||||
|
# 值的类型:tuple 或者 list
|
||||||
|
字段名称=("between", 值)
|
||||||
|
|
||||||
|
# 月份查询
|
||||||
|
# 值的类型:str
|
||||||
|
# 值的格式:%Y-%m:2023-05
|
||||||
|
字段名称=("month", 值)
|
||||||
|
|
||||||
|
# 不等于查询
|
||||||
|
字段名称=("!=", 值)
|
||||||
|
|
||||||
|
# 大于查询
|
||||||
|
字段名称=(">", 值)
|
||||||
|
|
||||||
|
# 等于 None
|
||||||
|
字段名称=("None")
|
||||||
|
|
||||||
|
# 不等于 None
|
||||||
|
字段名称=("not None")
|
||||||
|
```
|
||||||
|
|
||||||
|
代码部分:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
示例:
|
||||||
|
|
||||||
|
查询所有用户id为1或2或 4或6,并且email不为空,并且名称包括李:
|
||||||
|
|
||||||
|
```python
|
||||||
|
users = UserDal(db).get_datas(limit=0, id=("in", [1,2,4,6]), email=("not None"), name=("like", "李"))
|
||||||
|
```
|
||||||
|
|
||||||
|
### v_join_query
|
||||||
|
|
||||||
|
外键字段查询,内连接
|
||||||
|
|
||||||
|
以常见问题类别表为例:
|
||||||
|
|
||||||
|
首先需要在 `crud.py/IssueCategoryDal` 的 `__init__` 方法中定义 `key_models`:
|
||||||
|
|
||||||
|
```python
|
||||||
|
class IssueCategoryDal(DalBase):
|
||||||
|
|
||||||
|
def __init__(self, db: AsyncSession):
|
||||||
|
key_models = {
|
||||||
|
# 外键字段名,也可以自定义
|
||||||
|
"create_user": {
|
||||||
|
# 外键对应的orm模型
|
||||||
|
"model": vadminAuthModels.VadminUser,
|
||||||
|
# 如果对同一个模型只有一个外键关联时,下面这个 onclause 可以省略不写,一个以上时必须写,需要分清楚要查询的是哪个
|
||||||
|
# 这里其实可以省略不写,但是为了演示这里写出来了
|
||||||
|
"onclause": models.VadminIssueCategory.create_user_id == vadminAuthModels.VadminUser.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
super(IssueCategoryDal, self).__init__(
|
||||||
|
db,
|
||||||
|
models.VadminIssueCategory,
|
||||||
|
schemas.IssueCategorySimpleOut,
|
||||||
|
key_models
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
使用案例:
|
||||||
|
|
||||||
|
```python
|
||||||
|
async def test(self):
|
||||||
|
"""
|
||||||
|
v_join_query 示例方法
|
||||||
|
获取用户名称包含李 创建出的常见问题类别
|
||||||
|
"""
|
||||||
|
v_join_query = {
|
||||||
|
# 与 key_models 中定义的外键字段名定义的一样
|
||||||
|
"create_user": {
|
||||||
|
# 外键表字段名:查询值
|
||||||
|
"name": ("like", "李")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
v_options = [joinedload(self.model.create_user)]
|
||||||
|
datas = self.get_datas(limit=0, v_join_query=v_join_query, v_options=v_options)
|
||||||
|
```
|
||||||
|
|
||||||
|
完整案例:
|
||||||
|
|
||||||
|
```python
|
||||||
|
class IssueCategoryDal(DalBase):
|
||||||
|
|
||||||
|
def __init__(self, db: AsyncSession):
|
||||||
|
key_models = {
|
||||||
|
# 外键字段名,也可以自定义
|
||||||
|
"create_user": {
|
||||||
|
# 外键对应的orm模型
|
||||||
|
"model": vadminAuthModels.VadminUser,
|
||||||
|
# 如果对同一个模型只有一个外键关联时,下面这个 onclause 可以省略不写,一个以上时必须写,需要分清楚要查询的是哪个
|
||||||
|
# 这里其实可以省略不写,但是为了演示这里写出来了
|
||||||
|
"onclause": models.VadminIssueCategory.create_user_id == vadminAuthModels.VadminUser.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
super(IssueCategoryDal, self).__init__(
|
||||||
|
db,
|
||||||
|
models.VadminIssueCategory,
|
||||||
|
schemas.IssueCategorySimpleOut,
|
||||||
|
key_models
|
||||||
|
)
|
||||||
|
|
||||||
|
async def test(self):
|
||||||
|
"""
|
||||||
|
v_join_query 示例方法
|
||||||
|
获取用户名称包含李 创建出的常见问题类别
|
||||||
|
"""
|
||||||
|
v_join_query = {
|
||||||
|
# 与 key_models 中定义的外键字段名定义的一样
|
||||||
|
"create_user": {
|
||||||
|
# 外键表字段名:查询值
|
||||||
|
"name": ("like", "李")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
v_options = [joinedload(self.model.create_user)]
|
||||||
|
datas = self.get_datas(limit=0, v_join_query=v_join_query, v_options=v_options)
|
||||||
|
```
|
||||||
|
|
||||||
|
### v_or
|
||||||
|
|
||||||
|
或逻辑运算查询
|
||||||
|
|
||||||
|
语法:
|
||||||
|
|
||||||
|
```python
|
||||||
|
# 普通查询
|
||||||
|
v_or = [(字段名称, 值), (字段名称, 值), ... ]
|
||||||
|
|
||||||
|
# 模糊查询
|
||||||
|
v_or = [(字段名称, ("like", 值)), (字段名称, ("like", 值)), ... ]
|
||||||
|
|
||||||
|
# 组合查询
|
||||||
|
v_or = [(字段名称, ("like", 值)), (字段名称, ("in", [值, 值, 值, ...])), ... ]
|
||||||
|
|
||||||
|
# 外键查询,需要先定义 key_models
|
||||||
|
v_or = [("fk", key_models 中定义的外键字段名, 外键表字段名称, ("like", 值)), ("fk", key_models 中定义的外键字段名, 外键表字段名称, ("like", 值)), ... ]
|
||||||
|
```
|
||||||
|
|
||||||
|
比如查询一个用户手机号为`13409090909`或者`15390909090`:
|
||||||
|
|
||||||
|
```python
|
||||||
|
v_or = [("telephone", "13409090909"), ("telephone", "15390909090") ]
|
||||||
|
user = UserDal(db).get_data(v_or=v_or)
|
||||||
|
```
|
||||||
|
|
||||||
|
的version目录中多个迁移文件
|
@ -11,7 +11,7 @@ from fastapi.security import OAuth2PasswordBearer
|
|||||||
"""
|
"""
|
||||||
系统版本
|
系统版本
|
||||||
"""
|
"""
|
||||||
VERSION = "1.7.9"
|
VERSION = "1.8.0"
|
||||||
|
|
||||||
"""安全警告: 不要在生产中打开调试运行!"""
|
"""安全警告: 不要在生产中打开调试运行!"""
|
||||||
DEBUG = True
|
DEBUG = True
|
||||||
@ -20,11 +20,11 @@ DEBUG = True
|
|||||||
DEMO = not DEBUG
|
DEMO = not DEBUG
|
||||||
"""演示功能白名单"""
|
"""演示功能白名单"""
|
||||||
DEMO_WHITE_LIST_PATH = [
|
DEMO_WHITE_LIST_PATH = [
|
||||||
"/auth/login/",
|
"/auth/login",
|
||||||
"/auth/token/refresh/",
|
"/auth/token/refresh",
|
||||||
"/auth/wx/login/",
|
"/auth/wx/login",
|
||||||
"/vadmin/system/dict/types/details/",
|
"/vadmin/system/dict/types/details",
|
||||||
"/vadmin/auth/user/export/query/list/to/excel/"
|
"/vadmin/auth/user/export/query/list/to/excel"
|
||||||
]
|
]
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
@ -17,7 +17,7 @@ app = APIRouter()
|
|||||||
###########################################################
|
###########################################################
|
||||||
# 图表数据
|
# 图表数据
|
||||||
###########################################################
|
###########################################################
|
||||||
@app.get("/banners/", summary="轮播图")
|
@app.get("/banners", summary="轮播图")
|
||||||
async def get_banners(auth: Auth = Depends(AllUserAuth())):
|
async def get_banners(auth: Auth = Depends(AllUserAuth())):
|
||||||
data = [
|
data = [
|
||||||
{
|
{
|
||||||
@ -33,7 +33,7 @@ async def get_banners(auth: Auth = Depends(AllUserAuth())):
|
|||||||
return SuccessResponse(data)
|
return SuccessResponse(data)
|
||||||
|
|
||||||
|
|
||||||
@app.get("/user/access/source/", summary="用户来源")
|
@app.get("/user/access/source", summary="用户来源")
|
||||||
async def get_user_access_source(auth: Auth = Depends(AllUserAuth())):
|
async def get_user_access_source(auth: Auth = Depends(AllUserAuth())):
|
||||||
data = [
|
data = [
|
||||||
{"value": 1000, "name": 'analysis.directAccess'},
|
{"value": 1000, "name": 'analysis.directAccess'},
|
||||||
@ -45,7 +45,7 @@ async def get_user_access_source(auth: Auth = Depends(AllUserAuth())):
|
|||||||
return SuccessResponse(data)
|
return SuccessResponse(data)
|
||||||
|
|
||||||
|
|
||||||
@app.get("/weekly/user/activity/", summary="每周用户活跃量")
|
@app.get("/weekly/user/activity", summary="每周用户活跃量")
|
||||||
async def get_weekly_user_activity(auth: Auth = Depends(AllUserAuth())):
|
async def get_weekly_user_activity(auth: Auth = Depends(AllUserAuth())):
|
||||||
data = [
|
data = [
|
||||||
{"value": 13253, "name": 'analysis.monday'},
|
{"value": 13253, "name": 'analysis.monday'},
|
||||||
@ -59,7 +59,7 @@ async def get_weekly_user_activity(auth: Auth = Depends(AllUserAuth())):
|
|||||||
return SuccessResponse(data)
|
return SuccessResponse(data)
|
||||||
|
|
||||||
|
|
||||||
@app.get("/monthly/sales/", summary="每月销售额")
|
@app.get("/monthly/sales", summary="每月销售额")
|
||||||
async def get_monthly_sales(auth: Auth = Depends(AllUserAuth())):
|
async def get_monthly_sales(auth: Auth = Depends(AllUserAuth())):
|
||||||
data = [
|
data = [
|
||||||
{"estimate": 100, "actual": 120, "name": 'analysis.january'},
|
{"estimate": 100, "actual": 120, "name": 'analysis.january'},
|
||||||
|
@ -59,7 +59,7 @@ class VadminUser(BaseModel):
|
|||||||
self.last_login = datetime.datetime.now()
|
self.last_login = datetime.datetime.now()
|
||||||
await db.flush()
|
await db.flush()
|
||||||
|
|
||||||
async def is_admin(self) -> bool:
|
def is_admin(self) -> bool:
|
||||||
"""
|
"""
|
||||||
获取该用户是否拥有最高权限
|
获取该用户是否拥有最高权限
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ import jwt
|
|||||||
app = APIRouter()
|
app = APIRouter()
|
||||||
|
|
||||||
|
|
||||||
@app.post("/login/", summary="手机号密码登录", description="员工登录通道,限制最多输错次数,达到最大值后将is_active=False")
|
@app.post("/login", summary="手机号密码登录", description="员工登录通道,限制最多输错次数,达到最大值后将is_active=False")
|
||||||
async def login_for_access_token(
|
async def login_for_access_token(
|
||||||
request: Request,
|
request: Request,
|
||||||
data: LoginForm,
|
data: LoginForm,
|
||||||
@ -74,7 +74,7 @@ async def login_for_access_token(
|
|||||||
return ErrorResponse(msg=str(e))
|
return ErrorResponse(msg=str(e))
|
||||||
|
|
||||||
|
|
||||||
@app.post("/wx/login/", summary="微信服务端一键登录", description="员工登录通道")
|
@app.post("/wx/login", summary="微信服务端一键登录", description="员工登录通道")
|
||||||
async def wx_login_for_access_token(
|
async def wx_login_for_access_token(
|
||||||
request: Request,
|
request: Request,
|
||||||
data: WXLoginForm,
|
data: WXLoginForm,
|
||||||
@ -116,12 +116,12 @@ async def wx_login_for_access_token(
|
|||||||
return SuccessResponse(resp)
|
return SuccessResponse(resp)
|
||||||
|
|
||||||
|
|
||||||
@app.get("/getMenuList/", summary="获取当前用户菜单树")
|
@app.get("/getMenuList", summary="获取当前用户菜单树")
|
||||||
async def get_menu_list(auth: Auth = Depends(FullAdminAuth())):
|
async def get_menu_list(auth: Auth = Depends(FullAdminAuth())):
|
||||||
return SuccessResponse(await MenuDal(auth.db).get_routers(auth.user))
|
return SuccessResponse(await MenuDal(auth.db).get_routers(auth.user))
|
||||||
|
|
||||||
|
|
||||||
@app.post("/token/refresh/", summary="刷新Token")
|
@app.post("/token/refresh", summary="刷新Token")
|
||||||
async def token_refresh(refresh: str = Body(..., title="刷新Token")):
|
async def token_refresh(refresh: str = Body(..., title="刷新Token")):
|
||||||
error_code = status.HTTP_401_UNAUTHORIZED
|
error_code = status.HTTP_401_UNAUTHORIZED
|
||||||
try:
|
try:
|
||||||
|
@ -11,6 +11,7 @@ from fastapi import Request
|
|||||||
from application import settings
|
from application import settings
|
||||||
import jwt
|
import jwt
|
||||||
from apps.vadmin.auth import models
|
from apps.vadmin.auth import models
|
||||||
|
from core.database import redis_getter
|
||||||
from .validation import LoginValidation, LoginForm, LoginResult
|
from .validation import LoginValidation, LoginForm, LoginResult
|
||||||
from utils.aliyun_sms import AliyunSMS
|
from utils.aliyun_sms import AliyunSMS
|
||||||
|
|
||||||
@ -35,7 +36,7 @@ class LoginManage:
|
|||||||
"""
|
"""
|
||||||
验证用户短信验证码
|
验证用户短信验证码
|
||||||
"""
|
"""
|
||||||
rd = request.app.state.redis
|
rd = redis_getter(request)
|
||||||
sms = AliyunSMS(rd, data.telephone)
|
sms = AliyunSMS(rd, data.telephone)
|
||||||
result = await sms.check_sms_code(data.password)
|
result = await sms.check_sms_code(data.password)
|
||||||
if result:
|
if result:
|
||||||
|
@ -25,12 +25,17 @@ class Auth(BaseModel):
|
|||||||
|
|
||||||
|
|
||||||
class AuthValidation:
|
class AuthValidation:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
用于用户每次调用接口时,验证用户提交的token是否正确,并从token中获取用户信息
|
用于用户每次调用接口时,验证用户提交的token是否正确,并从token中获取用户信息
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# status_code = 401 时,表示强制要求重新登录,因账号已冻结,账号已过期,手机号码错误,刷新token无效等问题导致
|
||||||
|
# 只有 code = 401 时,表示 token 过期,要求刷新 token
|
||||||
|
# 只有 code = 错误值时,只是报错,不重新登陆
|
||||||
error_code = status.HTTP_401_UNAUTHORIZED
|
error_code = status.HTTP_401_UNAUTHORIZED
|
||||||
|
warning_code = status.HTTP_ERROR
|
||||||
|
|
||||||
|
# status_code = 403 时,表示强制要求重新登录,因无系统权限,而进入到系统访问等问题导致
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def validate_token(cls, request: Request, token: str | None) -> str:
|
def validate_token(cls, request: Request, token: str | None) -> str:
|
||||||
@ -38,14 +43,23 @@ class AuthValidation:
|
|||||||
验证用户 token
|
验证用户 token
|
||||||
"""
|
"""
|
||||||
if not token:
|
if not token:
|
||||||
raise CustomException(msg="请您先登录!", code=status.HTTP_ERROR)
|
raise CustomException(
|
||||||
|
msg="请您先登录!",
|
||||||
|
code=status.HTTP_403_FORBIDDEN,
|
||||||
|
status_code=status.HTTP_403_FORBIDDEN
|
||||||
|
)
|
||||||
try:
|
try:
|
||||||
|
# TODO token解析失败问题解决
|
||||||
payload = jwt.decode(token, settings.SECRET_KEY, algorithms=[settings.ALGORITHM])
|
payload = jwt.decode(token, settings.SECRET_KEY, algorithms=[settings.ALGORITHM])
|
||||||
telephone: str = payload.get("sub")
|
telephone: str = payload.get("sub")
|
||||||
exp: int = payload.get("exp")
|
exp: int = payload.get("exp")
|
||||||
is_refresh: bool = payload.get("is_refresh")
|
is_refresh: bool = payload.get("is_refresh")
|
||||||
if telephone is None or is_refresh:
|
if telephone is None or is_refresh:
|
||||||
raise CustomException(msg="未认证,请您重新登录", code=cls.error_code)
|
raise CustomException(
|
||||||
|
msg="未认证,请您重新登录",
|
||||||
|
code=status.HTTP_403_FORBIDDEN,
|
||||||
|
status_code=status.HTTP_403_FORBIDDEN
|
||||||
|
)
|
||||||
# 计算当前时间 + 缓冲时间是否大于等于 JWT 过期时间
|
# 计算当前时间 + 缓冲时间是否大于等于 JWT 过期时间
|
||||||
buffer_time = (datetime.now() + timedelta(minutes=settings.ACCESS_TOKEN_CACHE_MINUTES)).timestamp()
|
buffer_time = (datetime.now() + timedelta(minutes=settings.ACCESS_TOKEN_CACHE_MINUTES)).timestamp()
|
||||||
# print("过期时间", exp, datetime.fromtimestamp(exp))
|
# print("过期时间", exp, datetime.fromtimestamp(exp))
|
||||||
@ -55,10 +69,14 @@ class AuthValidation:
|
|||||||
request.scope["if-refresh"] = 1
|
request.scope["if-refresh"] = 1
|
||||||
else:
|
else:
|
||||||
request.scope["if-refresh"] = 0
|
request.scope["if-refresh"] = 0
|
||||||
except jwt.exceptions.InvalidSignatureError:
|
except (jwt.exceptions.InvalidSignatureError, jwt.exceptions.DecodeError):
|
||||||
raise CustomException(msg="无效认证,请您重新登录", code=cls.error_code)
|
raise CustomException(
|
||||||
|
msg="无效认证,请您重新登录",
|
||||||
|
code=status.HTTP_403_FORBIDDEN,
|
||||||
|
status_code=status.HTTP_403_FORBIDDEN
|
||||||
|
)
|
||||||
except jwt.exceptions.ExpiredSignatureError:
|
except jwt.exceptions.ExpiredSignatureError:
|
||||||
raise CustomException(msg="认证已过期,请您重新登录", code=cls.error_code)
|
raise CustomException(msg="认证已过期,请您重新登录", code=cls.error_code, status_code=cls.error_code)
|
||||||
return telephone
|
return telephone
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -84,7 +102,7 @@ class AuthValidation:
|
|||||||
"""
|
"""
|
||||||
获取员工用户所有权限列表
|
获取员工用户所有权限列表
|
||||||
"""
|
"""
|
||||||
if any([role.is_admin for role in user.roles]):
|
if user.is_admin():
|
||||||
return {'*.*.*'}
|
return {'*.*.*'}
|
||||||
permissions = set()
|
permissions = set()
|
||||||
for role_obj in user.roles:
|
for role_obj in user.roles:
|
||||||
|
@ -11,6 +11,7 @@ from pydantic import BaseModel, validator
|
|||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
from application.settings import DEFAULT_AUTH_ERROR_MAX_NUMBER, DEMO
|
from application.settings import DEFAULT_AUTH_ERROR_MAX_NUMBER, DEMO
|
||||||
from apps.vadmin.auth import crud, schemas
|
from apps.vadmin.auth import crud, schemas
|
||||||
|
from core.database import redis_getter
|
||||||
from core.validator import vali_telephone
|
from core.validator import vali_telephone
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from utils.count import Count
|
from utils.count import Count
|
||||||
@ -64,7 +65,7 @@ class LoginValidation:
|
|||||||
result = await self.func(self, data=data, user=user, request=request)
|
result = await self.func(self, data=data, user=user, request=request)
|
||||||
|
|
||||||
count_key = f"{data.telephone}_password_auth" if data.method == '0' else f"{data.telephone}_sms_auth"
|
count_key = f"{data.telephone}_password_auth" if data.method == '0' else f"{data.telephone}_sms_auth"
|
||||||
count = Count(request.app.state.redis, count_key)
|
count = Count(redis_getter(request), count_key)
|
||||||
|
|
||||||
if not result.status:
|
if not result.status:
|
||||||
self.result.msg = result.msg
|
self.result.msg = result.msg
|
||||||
|
@ -23,7 +23,7 @@ app = APIRouter()
|
|||||||
###########################################################
|
###########################################################
|
||||||
# 用户管理
|
# 用户管理
|
||||||
###########################################################
|
###########################################################
|
||||||
@app.get("/users/", summary="获取用户列表")
|
@app.get("/users", summary="获取用户列表")
|
||||||
async def get_users(
|
async def get_users(
|
||||||
params: UserParams = Depends(),
|
params: UserParams = Depends(),
|
||||||
auth: Auth = Depends(FullAdminAuth(permissions=["auth.user.list"]))
|
auth: Auth = Depends(FullAdminAuth(permissions=["auth.user.list"]))
|
||||||
@ -36,12 +36,12 @@ async def get_users(
|
|||||||
return SuccessResponse(datas, count=count)
|
return SuccessResponse(datas, count=count)
|
||||||
|
|
||||||
|
|
||||||
@app.post("/users/", summary="创建用户")
|
@app.post("/users", summary="创建用户")
|
||||||
async def create_user(data: schemas.UserIn, auth: Auth = Depends(FullAdminAuth(permissions=["auth.user.create"]))):
|
async def create_user(data: schemas.UserIn, auth: Auth = Depends(FullAdminAuth(permissions=["auth.user.create"]))):
|
||||||
return SuccessResponse(await crud.UserDal(auth.db).create_data(data=data))
|
return SuccessResponse(await crud.UserDal(auth.db).create_data(data=data))
|
||||||
|
|
||||||
|
|
||||||
@app.delete("/users/", summary="批量删除用户", description="软删除,删除后清空所关联的角色")
|
@app.delete("/users", summary="批量删除用户", description="软删除,删除后清空所关联的角色")
|
||||||
async def delete_users(ids: IdList = Depends(), auth: Auth = Depends(FullAdminAuth(permissions=["auth.user.delete"]))):
|
async def delete_users(ids: IdList = Depends(), auth: Auth = Depends(FullAdminAuth(permissions=["auth.user.delete"]))):
|
||||||
if auth.user.id in ids.ids:
|
if auth.user.id in ids.ids:
|
||||||
return ErrorResponse("不能删除当前登录用户")
|
return ErrorResponse("不能删除当前登录用户")
|
||||||
@ -51,7 +51,7 @@ async def delete_users(ids: IdList = Depends(), auth: Auth = Depends(FullAdminAu
|
|||||||
return SuccessResponse("删除成功")
|
return SuccessResponse("删除成功")
|
||||||
|
|
||||||
|
|
||||||
@app.put("/users/{data_id}/", summary="更新用户信息")
|
@app.put("/users/{data_id}", summary="更新用户信息")
|
||||||
async def put_user(
|
async def put_user(
|
||||||
data_id: int,
|
data_id: int,
|
||||||
data: schemas.UserUpdate,
|
data: schemas.UserUpdate,
|
||||||
@ -60,7 +60,7 @@ async def put_user(
|
|||||||
return SuccessResponse(await crud.UserDal(auth.db).put_data(data_id, data))
|
return SuccessResponse(await crud.UserDal(auth.db).put_data(data_id, data))
|
||||||
|
|
||||||
|
|
||||||
@app.get("/users/{data_id}/", summary="获取用户信息")
|
@app.get("/users/{data_id}", summary="获取用户信息")
|
||||||
async def get_user(
|
async def get_user(
|
||||||
data_id: int,
|
data_id: int,
|
||||||
auth: Auth = Depends(FullAdminAuth(permissions=["auth.user.view", "auth.user.update"]))
|
auth: Auth = Depends(FullAdminAuth(permissions=["auth.user.view", "auth.user.update"]))
|
||||||
@ -71,29 +71,29 @@ async def get_user(
|
|||||||
return SuccessResponse(await crud.UserDal(auth.db).get_data(data_id, options, v_schema=schema))
|
return SuccessResponse(await crud.UserDal(auth.db).get_data(data_id, options, v_schema=schema))
|
||||||
|
|
||||||
|
|
||||||
@app.post("/user/current/reset/password/", summary="重置当前用户密码")
|
@app.post("/user/current/reset/password", summary="重置当前用户密码")
|
||||||
async def user_current_reset_password(data: schemas.ResetPwd, auth: Auth = Depends(AllUserAuth())):
|
async def user_current_reset_password(data: schemas.ResetPwd, auth: Auth = Depends(AllUserAuth())):
|
||||||
return SuccessResponse(await crud.UserDal(auth.db).reset_current_password(auth.user, data))
|
return SuccessResponse(await crud.UserDal(auth.db).reset_current_password(auth.user, data))
|
||||||
|
|
||||||
|
|
||||||
@app.post("/user/current/update/info/", summary="更新当前用户基本信息")
|
@app.post("/user/current/update/info", summary="更新当前用户基本信息")
|
||||||
async def post_user_current_update_info(data: schemas.UserUpdateBaseInfo, auth: Auth = Depends(AllUserAuth())):
|
async def post_user_current_update_info(data: schemas.UserUpdateBaseInfo, auth: Auth = Depends(AllUserAuth())):
|
||||||
return SuccessResponse(await crud.UserDal(auth.db).update_current_info(auth.user, data))
|
return SuccessResponse(await crud.UserDal(auth.db).update_current_info(auth.user, data))
|
||||||
|
|
||||||
|
|
||||||
@app.post("/user/current/update/avatar/", summary="更新当前用户头像")
|
@app.post("/user/current/update/avatar", summary="更新当前用户头像")
|
||||||
async def post_user_current_update_avatar(file: UploadFile, auth: Auth = Depends(AllUserAuth())):
|
async def post_user_current_update_avatar(file: UploadFile, auth: Auth = Depends(AllUserAuth())):
|
||||||
return SuccessResponse(await crud.UserDal(auth.db).update_current_avatar(auth.user, file))
|
return SuccessResponse(await crud.UserDal(auth.db).update_current_avatar(auth.user, file))
|
||||||
|
|
||||||
|
|
||||||
@app.get("/user/admin/current/info/", summary="获取当前管理员信息")
|
@app.get("/user/admin/current/info", summary="获取当前管理员信息")
|
||||||
async def get_user_admin_current_info(auth: Auth = Depends(FullAdminAuth())):
|
async def get_user_admin_current_info(auth: Auth = Depends(FullAdminAuth())):
|
||||||
result = schemas.UserOut.from_orm(auth.user).dict()
|
result = schemas.UserOut.from_orm(auth.user).dict()
|
||||||
result["permissions"] = list(FullAdminAuth.get_user_permissions(auth.user))
|
result["permissions"] = list(FullAdminAuth.get_user_permissions(auth.user))
|
||||||
return SuccessResponse(result)
|
return SuccessResponse(result)
|
||||||
|
|
||||||
|
|
||||||
@app.post("/user/export/query/list/to/excel/", summary="导出用户查询列表为excel")
|
@app.post("/user/export/query/list/to/excel", summary="导出用户查询列表为excel")
|
||||||
async def post_user_export_query_list(
|
async def post_user_export_query_list(
|
||||||
header: list = Body(..., title="表头与对应字段"),
|
header: list = Body(..., title="表头与对应字段"),
|
||||||
params: UserParams = Depends(),
|
params: UserParams = Depends(),
|
||||||
@ -102,17 +102,17 @@ async def post_user_export_query_list(
|
|||||||
return SuccessResponse(await crud.UserDal(auth.db).export_query_list(header, params))
|
return SuccessResponse(await crud.UserDal(auth.db).export_query_list(header, params))
|
||||||
|
|
||||||
|
|
||||||
@app.get("/user/download/import/template/", summary="下载最新批量导入用户模板")
|
@app.get("/user/download/import/template", summary="下载最新批量导入用户模板")
|
||||||
async def get_user_download_new_import_template(auth: Auth = Depends(AllUserAuth())):
|
async def get_user_download_new_import_template(auth: Auth = Depends(AllUserAuth())):
|
||||||
return SuccessResponse(await crud.UserDal(auth.db).download_import_template())
|
return SuccessResponse(await crud.UserDal(auth.db).download_import_template())
|
||||||
|
|
||||||
|
|
||||||
@app.post("/import/users/", summary="批量导入用户")
|
@app.post("/import/users", summary="批量导入用户")
|
||||||
async def post_import_users(file: UploadFile, auth: Auth = Depends(FullAdminAuth(permissions=["auth.user.import"]))):
|
async def post_import_users(file: UploadFile, auth: Auth = Depends(FullAdminAuth(permissions=["auth.user.import"]))):
|
||||||
return SuccessResponse(await crud.UserDal(auth.db).import_users(file))
|
return SuccessResponse(await crud.UserDal(auth.db).import_users(file))
|
||||||
|
|
||||||
|
|
||||||
@app.post("/users/init/password/send/sms/", summary="初始化所选用户密码并发送通知短信")
|
@app.post("/users/init/password/send/sms", summary="初始化所选用户密码并发送通知短信")
|
||||||
async def post_users_init_password(
|
async def post_users_init_password(
|
||||||
request: Request,
|
request: Request,
|
||||||
ids: IdList = Depends(),
|
ids: IdList = Depends(),
|
||||||
@ -122,7 +122,7 @@ async def post_users_init_password(
|
|||||||
return SuccessResponse(await crud.UserDal(auth.db).init_password_send_sms(ids.ids, rd))
|
return SuccessResponse(await crud.UserDal(auth.db).init_password_send_sms(ids.ids, rd))
|
||||||
|
|
||||||
|
|
||||||
@app.post("/users/init/password/send/email/", summary="初始化所选用户密码并发送通知邮件")
|
@app.post("/users/init/password/send/email", summary="初始化所选用户密码并发送通知邮件")
|
||||||
async def post_users_init_password_send_email(
|
async def post_users_init_password_send_email(
|
||||||
request: Request,
|
request: Request,
|
||||||
ids: IdList = Depends(),
|
ids: IdList = Depends(),
|
||||||
@ -132,7 +132,7 @@ async def post_users_init_password_send_email(
|
|||||||
return SuccessResponse(await crud.UserDal(auth.db).init_password_send_email(ids.ids, rd))
|
return SuccessResponse(await crud.UserDal(auth.db).init_password_send_email(ids.ids, rd))
|
||||||
|
|
||||||
|
|
||||||
@app.put("/users/wx/server/openid/", summary="更新当前用户服务端微信平台openid")
|
@app.put("/users/wx/server/openid", summary="更新当前用户服务端微信平台openid")
|
||||||
async def put_user_wx_server_openid(code: str, auth: Auth = Depends(AllUserAuth()), rd: Redis = Depends(redis_getter)):
|
async def put_user_wx_server_openid(code: str, auth: Auth = Depends(AllUserAuth()), rd: Redis = Depends(redis_getter)):
|
||||||
result = await crud.UserDal(auth.db).update_wx_server_openid(code, auth.user, rd)
|
result = await crud.UserDal(auth.db).update_wx_server_openid(code, auth.user, rd)
|
||||||
return SuccessResponse(result)
|
return SuccessResponse(result)
|
||||||
@ -141,7 +141,7 @@ async def put_user_wx_server_openid(code: str, auth: Auth = Depends(AllUserAuth(
|
|||||||
###########################################################
|
###########################################################
|
||||||
# 角色管理
|
# 角色管理
|
||||||
###########################################################
|
###########################################################
|
||||||
@app.get("/roles/", summary="获取角色列表")
|
@app.get("/roles", summary="获取角色列表")
|
||||||
async def get_roles(
|
async def get_roles(
|
||||||
params: RoleParams = Depends(),
|
params: RoleParams = Depends(),
|
||||||
auth: Auth = Depends(FullAdminAuth(permissions=["auth.role.list"]))
|
auth: Auth = Depends(FullAdminAuth(permissions=["auth.role.list"]))
|
||||||
@ -151,12 +151,12 @@ async def get_roles(
|
|||||||
return SuccessResponse(datas, count=count)
|
return SuccessResponse(datas, count=count)
|
||||||
|
|
||||||
|
|
||||||
@app.post("/roles/", summary="创建角色信息")
|
@app.post("/roles", summary="创建角色信息")
|
||||||
async def create_role(role: schemas.RoleIn, auth: Auth = Depends(FullAdminAuth(permissions=["auth.role.create"]))):
|
async def create_role(role: schemas.RoleIn, auth: Auth = Depends(FullAdminAuth(permissions=["auth.role.create"]))):
|
||||||
return SuccessResponse(await crud.RoleDal(auth.db).create_data(data=role))
|
return SuccessResponse(await crud.RoleDal(auth.db).create_data(data=role))
|
||||||
|
|
||||||
|
|
||||||
@app.delete("/roles/", summary="批量删除角色", description="硬删除, 如果存在用户关联则无法删除")
|
@app.delete("/roles", summary="批量删除角色", description="硬删除, 如果存在用户关联则无法删除")
|
||||||
async def delete_roles(ids: IdList = Depends(), auth: Auth = Depends(FullAdminAuth(permissions=["auth.role.delete"]))):
|
async def delete_roles(ids: IdList = Depends(), auth: Auth = Depends(FullAdminAuth(permissions=["auth.role.delete"]))):
|
||||||
if 1 in ids.ids:
|
if 1 in ids.ids:
|
||||||
return ErrorResponse("不能删除管理员角色")
|
return ErrorResponse("不能删除管理员角色")
|
||||||
@ -164,7 +164,7 @@ async def delete_roles(ids: IdList = Depends(), auth: Auth = Depends(FullAdminAu
|
|||||||
return SuccessResponse("删除成功")
|
return SuccessResponse("删除成功")
|
||||||
|
|
||||||
|
|
||||||
@app.put("/roles/{data_id}/", summary="更新角色信息")
|
@app.put("/roles/{data_id}", summary="更新角色信息")
|
||||||
async def put_role(
|
async def put_role(
|
||||||
data_id: int,
|
data_id: int,
|
||||||
data: schemas.RoleIn,
|
data: schemas.RoleIn,
|
||||||
@ -175,12 +175,12 @@ async def put_role(
|
|||||||
return SuccessResponse(await crud.RoleDal(auth.db).put_data(data_id, data))
|
return SuccessResponse(await crud.RoleDal(auth.db).put_data(data_id, data))
|
||||||
|
|
||||||
|
|
||||||
@app.get("/roles/options/", summary="获取角色选择项")
|
@app.get("/roles/options", summary="获取角色选择项")
|
||||||
async def get_role_options(auth: Auth = Depends(FullAdminAuth(permissions=["auth.user.create", "auth.user.update"]))):
|
async def get_role_options(auth: Auth = Depends(FullAdminAuth(permissions=["auth.user.create", "auth.user.update"]))):
|
||||||
return SuccessResponse(await crud.RoleDal(auth.db).get_select_datas())
|
return SuccessResponse(await crud.RoleDal(auth.db).get_select_datas())
|
||||||
|
|
||||||
|
|
||||||
@app.get("/roles/{data_id}/", summary="获取角色信息")
|
@app.get("/roles/{data_id}", summary="获取角色信息")
|
||||||
async def get_role(
|
async def get_role(
|
||||||
data_id: int,
|
data_id: int,
|
||||||
auth: Auth = Depends(FullAdminAuth(permissions=["auth.role.view", "auth.role.update"]))
|
auth: Auth = Depends(FullAdminAuth(permissions=["auth.role.view", "auth.role.update"]))
|
||||||
@ -194,39 +194,39 @@ async def get_role(
|
|||||||
###########################################################
|
###########################################################
|
||||||
# 菜单管理
|
# 菜单管理
|
||||||
###########################################################
|
###########################################################
|
||||||
@app.get("/menus/", summary="获取菜单列表")
|
@app.get("/menus", summary="获取菜单列表")
|
||||||
async def get_menus(auth: Auth = Depends(FullAdminAuth(permissions=["auth.menu.list"]))):
|
async def get_menus(auth: Auth = Depends(FullAdminAuth(permissions=["auth.menu.list"]))):
|
||||||
datas = await crud.MenuDal(auth.db).get_tree_list(mode=1)
|
datas = await crud.MenuDal(auth.db).get_tree_list(mode=1)
|
||||||
return SuccessResponse(datas)
|
return SuccessResponse(datas)
|
||||||
|
|
||||||
|
|
||||||
@app.get("/menus/tree/options/", summary="获取菜单树选择项,添加/修改菜单时使用")
|
@app.get("/menus/tree/options", summary="获取菜单树选择项,添加/修改菜单时使用")
|
||||||
async def get_menus_options(auth: Auth = Depends(FullAdminAuth(permissions=["auth.menu.create", "auth.menu.update"]))):
|
async def get_menus_options(auth: Auth = Depends(FullAdminAuth(permissions=["auth.menu.create", "auth.menu.update"]))):
|
||||||
datas = await crud.MenuDal(auth.db).get_tree_list(mode=2)
|
datas = await crud.MenuDal(auth.db).get_tree_list(mode=2)
|
||||||
return SuccessResponse(datas)
|
return SuccessResponse(datas)
|
||||||
|
|
||||||
|
|
||||||
@app.get("/menus/role/tree/options/", summary="获取菜单列表树信息,角色权限使用")
|
@app.get("/menus/role/tree/options", summary="获取菜单列表树信息,角色权限使用")
|
||||||
async def get_menus_treeselect(
|
async def get_menus_treeselect(
|
||||||
auth: Auth = Depends(FullAdminAuth(permissions=["auth.role.create", "auth.role.update"]))
|
auth: Auth = Depends(FullAdminAuth(permissions=["auth.role.create", "auth.role.update"]))
|
||||||
):
|
):
|
||||||
return SuccessResponse(await crud.MenuDal(auth.db).get_tree_list(mode=3))
|
return SuccessResponse(await crud.MenuDal(auth.db).get_tree_list(mode=3))
|
||||||
|
|
||||||
|
|
||||||
@app.post("/menus/", summary="创建菜单信息")
|
@app.post("/menus", summary="创建菜单信息")
|
||||||
async def create_menu(menu: schemas.Menu, auth: Auth = Depends(FullAdminAuth(permissions=["auth.menu.create"]))):
|
async def create_menu(menu: schemas.Menu, auth: Auth = Depends(FullAdminAuth(permissions=["auth.menu.create"]))):
|
||||||
if menu.parent_id:
|
if menu.parent_id:
|
||||||
menu.alwaysShow = False
|
menu.alwaysShow = False
|
||||||
return SuccessResponse(await crud.MenuDal(auth.db).create_data(data=menu))
|
return SuccessResponse(await crud.MenuDal(auth.db).create_data(data=menu))
|
||||||
|
|
||||||
|
|
||||||
@app.delete("/menus/", summary="批量删除菜单", description="硬删除, 如果存在角色关联则无法删除")
|
@app.delete("/menus", summary="批量删除菜单", description="硬删除, 如果存在角色关联则无法删除")
|
||||||
async def delete_menus(ids: IdList = Depends(), auth: Auth = Depends(FullAdminAuth(permissions=["auth.menu.delete"]))):
|
async def delete_menus(ids: IdList = Depends(), auth: Auth = Depends(FullAdminAuth(permissions=["auth.menu.delete"]))):
|
||||||
await crud.MenuDal(auth.db).delete_datas(ids.ids, v_soft=False)
|
await crud.MenuDal(auth.db).delete_datas(ids.ids, v_soft=False)
|
||||||
return SuccessResponse("删除成功")
|
return SuccessResponse("删除成功")
|
||||||
|
|
||||||
|
|
||||||
@app.put("/menus/{data_id}/", summary="更新菜单信息")
|
@app.put("/menus/{data_id}", summary="更新菜单信息")
|
||||||
async def put_menus(
|
async def put_menus(
|
||||||
data_id: int,
|
data_id: int,
|
||||||
data: schemas.Menu, auth: Auth = Depends(FullAdminAuth(permissions=["auth.menu.update"]))
|
data: schemas.Menu, auth: Auth = Depends(FullAdminAuth(permissions=["auth.menu.update"]))
|
||||||
@ -234,7 +234,7 @@ async def put_menus(
|
|||||||
return SuccessResponse(await crud.MenuDal(auth.db).put_data(data_id, data))
|
return SuccessResponse(await crud.MenuDal(auth.db).put_data(data_id, data))
|
||||||
|
|
||||||
|
|
||||||
@app.get("/menus/{data_id}/", summary="获取菜单信息")
|
@app.get("/menus/{data_id}", summary="获取菜单信息")
|
||||||
async def put_menus(
|
async def put_menus(
|
||||||
data_id: int,
|
data_id: int,
|
||||||
auth: Auth = Depends(FullAdminAuth(permissions=["auth.menu.view", "auth.menu.update"]))
|
auth: Auth = Depends(FullAdminAuth(permissions=["auth.menu.view", "auth.menu.update"]))
|
||||||
@ -243,7 +243,7 @@ async def put_menus(
|
|||||||
return SuccessResponse(await crud.MenuDal(auth.db).get_data(data_id, None, v_schema=schema))
|
return SuccessResponse(await crud.MenuDal(auth.db).get_data(data_id, None, v_schema=schema))
|
||||||
|
|
||||||
|
|
||||||
@app.get("/role/menus/tree/{role_id}/", summary="获取菜单列表树信息以及角色菜单权限ID,角色权限使用")
|
@app.get("/role/menus/tree/{role_id}", summary="获取菜单列表树信息以及角色菜单权限ID,角色权限使用")
|
||||||
async def get_role_menu_tree(
|
async def get_role_menu_tree(
|
||||||
role_id: int,
|
role_id: int,
|
||||||
auth: Auth = Depends(FullAdminAuth(permissions=["auth.role.create", "auth.role.update"]))
|
auth: Auth = Depends(FullAdminAuth(permissions=["auth.role.create", "auth.role.update"]))
|
||||||
|
@ -5,11 +5,13 @@
|
|||||||
# @File : crud.py
|
# @File : crud.py
|
||||||
# @IDE : PyCharm
|
# @IDE : PyCharm
|
||||||
# @desc : 帮助中心 - 增删改查
|
# @desc : 帮助中心 - 增删改查
|
||||||
from typing import List
|
|
||||||
|
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
from sqlalchemy.orm import joinedload
|
||||||
|
|
||||||
from core.crud import DalBase
|
from core.crud import DalBase
|
||||||
from . import models, schemas
|
from . import models, schemas
|
||||||
|
from apps.vadmin.auth import models as vadminAuthModels
|
||||||
|
|
||||||
|
|
||||||
class IssueDal(DalBase):
|
class IssueDal(DalBase):
|
||||||
@ -30,5 +32,34 @@ class IssueDal(DalBase):
|
|||||||
class IssueCategoryDal(DalBase):
|
class IssueCategoryDal(DalBase):
|
||||||
|
|
||||||
def __init__(self, db: AsyncSession):
|
def __init__(self, db: AsyncSession):
|
||||||
super(IssueCategoryDal, self).__init__(db, models.VadminIssueCategory, schemas.IssueCategorySimpleOut)
|
key_models = {
|
||||||
|
# 外键字段名,也可以自定义
|
||||||
|
"create_user": {
|
||||||
|
# 外键对应的orm模型
|
||||||
|
"model": vadminAuthModels.VadminUser,
|
||||||
|
# 如果对同一个模型只有一个外键关联时,下面这个 onclause 可以省略不写,一个以上时必须写,需要分清楚要查询的是哪个
|
||||||
|
# 这里其实可以省略不写,但是为了演示这里写出来了
|
||||||
|
"onclause": models.VadminIssueCategory.create_user_id == vadminAuthModels.VadminUser.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
super(IssueCategoryDal, self).__init__(
|
||||||
|
db,
|
||||||
|
models.VadminIssueCategory,
|
||||||
|
schemas.IssueCategorySimpleOut,
|
||||||
|
key_models
|
||||||
|
)
|
||||||
|
|
||||||
|
async def test(self):
|
||||||
|
"""
|
||||||
|
v_join_query 示例方法
|
||||||
|
获取用户名称包含李 创建出的常见问题类别
|
||||||
|
"""
|
||||||
|
v_join_query = {
|
||||||
|
# 与 key_models 中定义的外键字段名定义的一样
|
||||||
|
"create_user": {
|
||||||
|
# 外键表字段名:查询值
|
||||||
|
"name": ("like", "李")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
v_options = [joinedload(self.model.create_user)]
|
||||||
|
datas = self.get_datas(limit=0, v_join_query=v_join_query, v_options=v_options)
|
||||||
|
@ -21,8 +21,8 @@ class VadminIssueCategory(BaseModel):
|
|||||||
|
|
||||||
issues = relationship("VadminIssue", back_populates='category')
|
issues = relationship("VadminIssue", back_populates='category')
|
||||||
|
|
||||||
user_id = Column(ForeignKey("vadmin_auth_user.id", ondelete='SET NULL'), comment="创建人")
|
create_user_id = Column(ForeignKey("vadmin_auth_user.id", ondelete='SET NULL'), comment="创建人")
|
||||||
user = relationship("VadminUser", foreign_keys=user_id)
|
create_user = relationship("VadminUser", foreign_keys=create_user_id)
|
||||||
|
|
||||||
|
|
||||||
class VadminIssue(BaseModel):
|
class VadminIssue(BaseModel):
|
||||||
@ -37,6 +37,6 @@ class VadminIssue(BaseModel):
|
|||||||
view_number = Column(Integer, default=0, comment="查看次数")
|
view_number = Column(Integer, default=0, comment="查看次数")
|
||||||
is_active = Column(Boolean, default=True, comment="是否可见")
|
is_active = Column(Boolean, default=True, comment="是否可见")
|
||||||
|
|
||||||
user_id = Column(ForeignKey("vadmin_auth_user.id", ondelete='SET NULL'), comment="创建人")
|
create_user_id = Column(ForeignKey("vadmin_auth_user.id", ondelete='SET NULL'), comment="创建人")
|
||||||
user = relationship("VadminUser", foreign_keys=user_id)
|
create_user = relationship("VadminUser", foreign_keys=create_user_id)
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ from .issue_category import IssueCategorySimpleOut
|
|||||||
|
|
||||||
class Issue(BaseModel):
|
class Issue(BaseModel):
|
||||||
category_id: Optional[int] = None
|
category_id: Optional[int] = None
|
||||||
user_id: Optional[int] = None
|
create_user_id: Optional[int] = None
|
||||||
|
|
||||||
title: Optional[str] = None
|
title: Optional[str] = None
|
||||||
content: Optional[str] = None
|
content: Optional[str] = None
|
||||||
@ -33,7 +33,7 @@ class IssueSimpleOut(Issue):
|
|||||||
|
|
||||||
|
|
||||||
class IssueListOut(IssueSimpleOut):
|
class IssueListOut(IssueSimpleOut):
|
||||||
user: UserSimpleOut
|
create_user: UserSimpleOut
|
||||||
category: IssueCategorySimpleOut
|
category: IssueCategorySimpleOut
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
|
@ -18,7 +18,7 @@ class IssueCategory(BaseModel):
|
|||||||
platform: Optional[str] = None
|
platform: Optional[str] = None
|
||||||
is_active: Optional[bool] = None
|
is_active: Optional[bool] = None
|
||||||
|
|
||||||
user_id: Optional[int] = None
|
create_user_id: Optional[int] = None
|
||||||
|
|
||||||
|
|
||||||
class IssueCategorySimpleOut(IssueCategory):
|
class IssueCategorySimpleOut(IssueCategory):
|
||||||
@ -31,7 +31,7 @@ class IssueCategorySimpleOut(IssueCategory):
|
|||||||
|
|
||||||
|
|
||||||
class IssueCategoryListOut(IssueCategorySimpleOut):
|
class IssueCategoryListOut(IssueCategorySimpleOut):
|
||||||
user: UserSimpleOut
|
create_user: UserSimpleOut
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
orm_mode = True
|
orm_mode = True
|
||||||
|
@ -16,7 +16,7 @@ class IssueCategoryPlatformOut(BaseModel):
|
|||||||
name: Optional[str] = None
|
name: Optional[str] = None
|
||||||
platform: Optional[str] = None
|
platform: Optional[str] = None
|
||||||
is_active: Optional[bool] = None
|
is_active: Optional[bool] = None
|
||||||
user_id: Optional[int] = None
|
create_user_id: Optional[int] = None
|
||||||
|
|
||||||
id: int
|
id: int
|
||||||
update_datetime: DatetimeStr
|
update_datetime: DatetimeStr
|
||||||
|
@ -22,91 +22,95 @@ app = APIRouter()
|
|||||||
###########################################################
|
###########################################################
|
||||||
# 类别管理
|
# 类别管理
|
||||||
###########################################################
|
###########################################################
|
||||||
@app.get("/issue/categorys/", summary="获取类别列表")
|
@app.get("/issue/categorys", summary="获取类别列表")
|
||||||
async def get_issue_categorys(p: params.IssueCategoryParams = Depends(), auth: Auth = Depends(AllUserAuth())):
|
async def get_issue_categorys(p: params.IssueCategoryParams = Depends(), auth: Auth = Depends(AllUserAuth())):
|
||||||
model = models.VadminIssueCategory
|
model = models.VadminIssueCategory
|
||||||
options = [joinedload(model.user)]
|
options = [joinedload(model.create_user)]
|
||||||
schema = schemas.IssueCategoryListOut
|
schema = schemas.IssueCategoryListOut
|
||||||
datas = await crud.IssueCategoryDal(auth.db).get_datas(**p.dict(), v_options=options, v_schema=schema)
|
datas = await crud.IssueCategoryDal(auth.db).get_datas(**p.dict(), v_options=options, v_schema=schema)
|
||||||
count = await crud.IssueCategoryDal(auth.db).get_count(**p.to_count())
|
count = await crud.IssueCategoryDal(auth.db).get_count(**p.to_count())
|
||||||
return SuccessResponse(datas, count=count)
|
return SuccessResponse(datas, count=count)
|
||||||
|
|
||||||
|
|
||||||
@app.get("/issue/categorys/options/", summary="获取类别选择项")
|
@app.get("/issue/categorys/options", summary="获取类别选择项")
|
||||||
async def get_issue_categorys_options(auth: Auth = Depends(AllUserAuth())):
|
async def get_issue_categorys_options(auth: Auth = Depends(AllUserAuth())):
|
||||||
schema = schemas.IssueCategoryOptionsOut
|
schema = schemas.IssueCategoryOptionsOut
|
||||||
return SuccessResponse(await crud.IssueCategoryDal(auth.db).get_datas(limit=0, is_active=True, v_schema=schema))
|
return SuccessResponse(await crud.IssueCategoryDal(auth.db).get_datas(limit=0, is_active=True, v_schema=schema))
|
||||||
|
|
||||||
|
|
||||||
@app.post("/issue/categorys/", summary="创建类别")
|
@app.post("/issue/categorys", summary="创建类别")
|
||||||
async def create_issue_category(data: schemas.IssueCategory, auth: Auth = Depends(AllUserAuth())):
|
async def create_issue_category(data: schemas.IssueCategory, auth: Auth = Depends(AllUserAuth())):
|
||||||
data.user_id = auth.user.id
|
data.create_user_id = auth.user.id
|
||||||
return SuccessResponse(await crud.IssueCategoryDal(auth.db).create_data(data=data))
|
return SuccessResponse(await crud.IssueCategoryDal(auth.db).create_data(data=data))
|
||||||
|
|
||||||
|
|
||||||
@app.delete("/issue/categorys/", summary="批量删除类别", description="硬删除")
|
@app.delete("/issue/categorys", summary="批量删除类别", description="硬删除")
|
||||||
async def delete_issue_categorys(ids: IdList = Depends(), auth: Auth = Depends(AllUserAuth())):
|
async def delete_issue_categorys(ids: IdList = Depends(), auth: Auth = Depends(AllUserAuth())):
|
||||||
await crud.IssueCategoryDal(auth.db).delete_datas(ids=ids.ids, v_soft=False)
|
await crud.IssueCategoryDal(auth.db).delete_datas(ids=ids.ids, v_soft=False)
|
||||||
return SuccessResponse("删除成功")
|
return SuccessResponse("删除成功")
|
||||||
|
|
||||||
|
|
||||||
@app.put("/issue/categorys/{data_id}/", summary="更新类别信息")
|
@app.put("/issue/categorys/{data_id}", summary="更新类别信息")
|
||||||
async def put_issue_category(data_id: int, data: schemas.IssueCategory, auth: Auth = Depends(AllUserAuth())):
|
async def put_issue_category(data_id: int, data: schemas.IssueCategory, auth: Auth = Depends(AllUserAuth())):
|
||||||
return SuccessResponse(await crud.IssueCategoryDal(auth.db).put_data(data_id, data))
|
return SuccessResponse(await crud.IssueCategoryDal(auth.db).put_data(data_id, data))
|
||||||
|
|
||||||
|
|
||||||
@app.get("/issue/categorys/{data_id}/", summary="获取类别信息")
|
@app.get("/issue/categorys/{data_id}", summary="获取类别信息")
|
||||||
async def get_issue_category(data_id: int, auth: Auth = Depends(AllUserAuth())):
|
async def get_issue_category(data_id: int, auth: Auth = Depends(AllUserAuth())):
|
||||||
schema = schemas.IssueCategorySimpleOut
|
schema = schemas.IssueCategorySimpleOut
|
||||||
return SuccessResponse(await crud.IssueCategoryDal(auth.db).get_data(data_id, v_schema=schema))
|
return SuccessResponse(await crud.IssueCategoryDal(auth.db).get_data(data_id, v_schema=schema))
|
||||||
|
|
||||||
|
|
||||||
@app.get("/issue/categorys/platform/{platform}/", summary="获取平台中的常见问题类别列表")
|
@app.get("/issue/categorys/platform/{platform}", summary="获取平台中的常见问题类别列表")
|
||||||
async def get_issue_category_platform(platform: str, db: AsyncSession = Depends(db_getter)):
|
async def get_issue_category_platform(platform: str, db: AsyncSession = Depends(db_getter)):
|
||||||
model = models.VadminIssueCategory
|
model = models.VadminIssueCategory
|
||||||
options = [joinedload(model.issues)]
|
options = [joinedload(model.issues)]
|
||||||
schema = schemas.IssueCategoryPlatformOut
|
schema = schemas.IssueCategoryPlatformOut
|
||||||
result = await crud.IssueCategoryDal(db).\
|
result = await crud.IssueCategoryDal(db).get_datas(
|
||||||
get_datas(platform=platform, is_active=True, v_schema=schema, v_options=options)
|
platform=platform,
|
||||||
|
is_active=True,
|
||||||
|
v_schema=schema,
|
||||||
|
v_options=options
|
||||||
|
)
|
||||||
return SuccessResponse(result)
|
return SuccessResponse(result)
|
||||||
|
|
||||||
|
|
||||||
###########################################################
|
###########################################################
|
||||||
# 问题管理
|
# 问题管理
|
||||||
###########################################################
|
###########################################################
|
||||||
@app.get("/issues/", summary="获取问题列表")
|
@app.get("/issues", summary="获取问题列表")
|
||||||
async def get_issues(p: params.IssueParams = Depends(), auth: Auth = Depends(AllUserAuth())):
|
async def get_issues(p: params.IssueParams = Depends(), auth: Auth = Depends(AllUserAuth())):
|
||||||
model = models.VadminIssue
|
model = models.VadminIssue
|
||||||
options = [joinedload(model.user), joinedload(model.category)]
|
options = [joinedload(model.create_user), joinedload(model.category)]
|
||||||
schema = schemas.IssueListOut
|
schema = schemas.IssueListOut
|
||||||
datas = await crud.IssueDal(auth.db).get_datas(**p.dict(), v_options=options, v_schema=schema)
|
datas = await crud.IssueDal(auth.db).get_datas(**p.dict(), v_options=options, v_schema=schema)
|
||||||
count = await crud.IssueDal(auth.db).get_count(**p.to_count())
|
count = await crud.IssueDal(auth.db).get_count(**p.to_count())
|
||||||
return SuccessResponse(datas, count=count)
|
return SuccessResponse(datas, count=count)
|
||||||
|
|
||||||
|
|
||||||
@app.post("/issues/", summary="创建问题")
|
@app.post("/issues", summary="创建问题")
|
||||||
async def create_issue(data: schemas.Issue, auth: Auth = Depends(AllUserAuth())):
|
async def create_issue(data: schemas.Issue, auth: Auth = Depends(AllUserAuth())):
|
||||||
data.user_id = auth.user.id
|
data.create_user_id = auth.user.id
|
||||||
return SuccessResponse(await crud.IssueDal(auth.db).create_data(data=data))
|
return SuccessResponse(await crud.IssueDal(auth.db).create_data(data=data))
|
||||||
|
|
||||||
|
|
||||||
@app.delete("/issues/", summary="批量删除问题", description="硬删除")
|
@app.delete("/issues", summary="批量删除问题", description="硬删除")
|
||||||
async def delete_issues(ids: IdList = Depends(), auth: Auth = Depends(AllUserAuth())):
|
async def delete_issues(ids: IdList = Depends(), auth: Auth = Depends(AllUserAuth())):
|
||||||
await crud.IssueDal(auth.db).delete_datas(ids=ids.ids, v_soft=False)
|
await crud.IssueDal(auth.db).delete_datas(ids=ids.ids, v_soft=False)
|
||||||
return SuccessResponse("删除成功")
|
return SuccessResponse("删除成功")
|
||||||
|
|
||||||
|
|
||||||
@app.put("/issues/{data_id}/", summary="更新问题信息")
|
@app.put("/issues/{data_id}", summary="更新问题信息")
|
||||||
async def put_issue(data_id: int, data: schemas.Issue, auth: Auth = Depends(AllUserAuth())):
|
async def put_issue(data_id: int, data: schemas.Issue, auth: Auth = Depends(AllUserAuth())):
|
||||||
return SuccessResponse(await crud.IssueDal(auth.db).put_data(data_id, data))
|
return SuccessResponse(await crud.IssueDal(auth.db).put_data(data_id, data))
|
||||||
|
|
||||||
|
|
||||||
@app.get("/issues/{data_id}/", summary="获取问题信息")
|
@app.get("/issues/{data_id}", summary="获取问题信息")
|
||||||
async def get_issue(data_id: int, db: AsyncSession = Depends(db_getter)):
|
async def get_issue(data_id: int, db: AsyncSession = Depends(db_getter)):
|
||||||
schema = schemas.IssueSimpleOut
|
schema = schemas.IssueSimpleOut
|
||||||
return SuccessResponse(await crud.IssueDal(db).get_data(data_id, v_schema=schema))
|
return SuccessResponse(await crud.IssueDal(db).get_data(data_id, v_schema=schema))
|
||||||
|
|
||||||
|
|
||||||
@app.get("/issues/add/view/number/{data_id}/", summary="更新常见问题查看次数+1")
|
@app.get("/issues/add/view/number/{data_id}", summary="更新常见问题查看次数+1")
|
||||||
async def issue_add_view_number(data_id: int, db: AsyncSession = Depends(db_getter)):
|
async def issue_add_view_number(data_id: int, db: AsyncSession = Depends(db_getter)):
|
||||||
return SuccessResponse(await crud.IssueDal(db).add_view_number(data_id))
|
return SuccessResponse(await crud.IssueDal(db).add_view_number(data_id))
|
||||||
|
@ -19,14 +19,14 @@ app = APIRouter()
|
|||||||
###########################################################
|
###########################################################
|
||||||
# 日志管理
|
# 日志管理
|
||||||
###########################################################
|
###########################################################
|
||||||
@app.get("/logins/", summary="获取登录日志列表")
|
@app.get("/logins", summary="获取登录日志列表")
|
||||||
async def get_record_login(p: LoginParams = Depends(), auth: Auth = Depends(AllUserAuth())):
|
async def get_record_login(p: LoginParams = Depends(), auth: Auth = Depends(AllUserAuth())):
|
||||||
datas = await crud.LoginRecordDal(auth.db).get_datas(**p.dict())
|
datas = await crud.LoginRecordDal(auth.db).get_datas(**p.dict())
|
||||||
count = await crud.LoginRecordDal(auth.db).get_count(**p.to_count())
|
count = await crud.LoginRecordDal(auth.db).get_count(**p.to_count())
|
||||||
return SuccessResponse(datas, count=count)
|
return SuccessResponse(datas, count=count)
|
||||||
|
|
||||||
|
|
||||||
@app.get("/operations/", summary="获取操作日志列表")
|
@app.get("/operations", summary="获取操作日志列表")
|
||||||
async def get_record_operation(
|
async def get_record_operation(
|
||||||
p: OperationParams = Depends(),
|
p: OperationParams = Depends(),
|
||||||
db: DatabaseManage = Depends(get_database),
|
db: DatabaseManage = Depends(get_database),
|
||||||
@ -37,7 +37,7 @@ async def get_record_operation(
|
|||||||
return SuccessResponse(datas, count=count)
|
return SuccessResponse(datas, count=count)
|
||||||
|
|
||||||
|
|
||||||
@app.get("/sms/send/list/", summary="获取短信发送列表")
|
@app.get("/sms/send/list", summary="获取短信发送列表")
|
||||||
async def get_sms_send_list(p: SMSParams = Depends(), auth: Auth = Depends(AllUserAuth())):
|
async def get_sms_send_list(p: SMSParams = Depends(), auth: Auth = Depends(AllUserAuth())):
|
||||||
datas = await crud.SMSSendRecordDal(auth.db).get_datas(**p.dict())
|
datas = await crud.SMSSendRecordDal(auth.db).get_datas(**p.dict())
|
||||||
count = await crud.SMSSendRecordDal(auth.db).get_count(**p.to_count())
|
count = await crud.SMSSendRecordDal(auth.db).get_count(**p.to_count())
|
||||||
@ -47,6 +47,6 @@ async def get_sms_send_list(p: SMSParams = Depends(), auth: Auth = Depends(AllUs
|
|||||||
###########################################################
|
###########################################################
|
||||||
# 日志分析
|
# 日志分析
|
||||||
###########################################################
|
###########################################################
|
||||||
@app.get("/analysis/user/login/distribute/", summary="获取用户登录分布情况列表")
|
@app.get("/analysis/user/login/distribute", summary="获取用户登录分布情况列表")
|
||||||
async def get_user_login_distribute(auth: Auth = Depends(AllUserAuth())):
|
async def get_user_login_distribute(auth: Auth = Depends(AllUserAuth())):
|
||||||
return SuccessResponse(await crud.LoginRecordDal(auth.db).get_user_distribute())
|
return SuccessResponse(await crud.LoginRecordDal(auth.db).get_user_distribute())
|
||||||
|
@ -95,7 +95,7 @@ class SettingsDal(DalBase):
|
|||||||
if ico.config_value == web_ico:
|
if ico.config_value == web_ico:
|
||||||
continue
|
continue
|
||||||
# 将上传的ico路径替换到static/system/favicon.ico文件
|
# 将上传的ico路径替换到static/system/favicon.ico文件
|
||||||
FileManage.copy(value, os.path.join(STATIC_ROOT, "system/favicon.ico"))
|
await FileManage.async_copy(value, os.path.join(STATIC_ROOT, "system/favicon.ico"))
|
||||||
sql = update(self.model).where(self.model.config_key == "web_ico").values(config_value=web_ico)
|
sql = update(self.model).where(self.model.config_key == "web_ico").values(config_value=web_ico)
|
||||||
await self.db.execute(sql)
|
await self.db.execute(sql)
|
||||||
else:
|
else:
|
||||||
|
@ -28,25 +28,25 @@ app = APIRouter()
|
|||||||
###########################################################
|
###########################################################
|
||||||
# 字典类型管理
|
# 字典类型管理
|
||||||
###########################################################
|
###########################################################
|
||||||
@app.get("/dict/types/", summary="获取字典类型列表")
|
@app.get("/dict/types", summary="获取字典类型列表")
|
||||||
async def get_dict_types(p: DictTypeParams = Depends(), auth: Auth = Depends(AllUserAuth())):
|
async def get_dict_types(p: DictTypeParams = Depends(), auth: Auth = Depends(AllUserAuth())):
|
||||||
datas = await crud.DictTypeDal(auth.db).get_datas(**p.dict())
|
datas = await crud.DictTypeDal(auth.db).get_datas(**p.dict())
|
||||||
count = await crud.DictTypeDal(auth.db).get_count(**p.to_count())
|
count = await crud.DictTypeDal(auth.db).get_count(**p.to_count())
|
||||||
return SuccessResponse(datas, count=count)
|
return SuccessResponse(datas, count=count)
|
||||||
|
|
||||||
|
|
||||||
@app.post("/dict/types/", summary="创建字典类型")
|
@app.post("/dict/types", summary="创建字典类型")
|
||||||
async def create_dict_types(data: schemas.DictType, auth: Auth = Depends(AllUserAuth())):
|
async def create_dict_types(data: schemas.DictType, auth: Auth = Depends(AllUserAuth())):
|
||||||
return SuccessResponse(await crud.DictTypeDal(auth.db).create_data(data=data))
|
return SuccessResponse(await crud.DictTypeDal(auth.db).create_data(data=data))
|
||||||
|
|
||||||
|
|
||||||
@app.delete("/dict/types/", summary="批量删除字典类型")
|
@app.delete("/dict/types", summary="批量删除字典类型")
|
||||||
async def delete_dict_types(ids: IdList = Depends(), auth: Auth = Depends(AllUserAuth())):
|
async def delete_dict_types(ids: IdList = Depends(), auth: Auth = Depends(AllUserAuth())):
|
||||||
await crud.DictTypeDal(auth.db).delete_datas(ids=ids.ids)
|
await crud.DictTypeDal(auth.db).delete_datas(ids=ids.ids)
|
||||||
return SuccessResponse("删除成功")
|
return SuccessResponse("删除成功")
|
||||||
|
|
||||||
|
|
||||||
@app.post("/dict/types/details/", summary="获取多个字典类型下的字典元素列表")
|
@app.post("/dict/types/details", summary="获取多个字典类型下的字典元素列表")
|
||||||
async def post_dicts_details(
|
async def post_dicts_details(
|
||||||
auth: Auth = Depends(AllUserAuth()),
|
auth: Auth = Depends(AllUserAuth()),
|
||||||
dict_types: List[str] = Body(None, title="字典元素列表", description="查询字典元素列表")
|
dict_types: List[str] = Body(None, title="字典元素列表", description="查询字典元素列表")
|
||||||
@ -55,17 +55,17 @@ async def post_dicts_details(
|
|||||||
return SuccessResponse(datas)
|
return SuccessResponse(datas)
|
||||||
|
|
||||||
|
|
||||||
@app.get("/dict/types/options/", summary="获取字典类型选择项")
|
@app.get("/dict/types/options", summary="获取字典类型选择项")
|
||||||
async def get_dicts_options(auth: Auth = Depends(AllUserAuth())):
|
async def get_dicts_options(auth: Auth = Depends(AllUserAuth())):
|
||||||
return SuccessResponse(await crud.DictTypeDal(auth.db).get_select_datas())
|
return SuccessResponse(await crud.DictTypeDal(auth.db).get_select_datas())
|
||||||
|
|
||||||
|
|
||||||
@app.put("/dict/types/{data_id}/", summary="更新字典类型")
|
@app.put("/dict/types/{data_id}", summary="更新字典类型")
|
||||||
async def put_dict_types(data_id: int, data: schemas.DictType, auth: Auth = Depends(AllUserAuth())):
|
async def put_dict_types(data_id: int, data: schemas.DictType, auth: Auth = Depends(AllUserAuth())):
|
||||||
return SuccessResponse(await crud.DictTypeDal(auth.db).put_data(data_id, data))
|
return SuccessResponse(await crud.DictTypeDal(auth.db).put_data(data_id, data))
|
||||||
|
|
||||||
|
|
||||||
@app.get("/dict/types/{data_id}/", summary="获取字典类型详细")
|
@app.get("/dict/types/{data_id}", summary="获取字典类型详细")
|
||||||
async def get_dict_type(data_id: int, auth: Auth = Depends(AllUserAuth())):
|
async def get_dict_type(data_id: int, auth: Auth = Depends(AllUserAuth())):
|
||||||
schema = schemas.DictTypeSimpleOut
|
schema = schemas.DictTypeSimpleOut
|
||||||
return SuccessResponse(await crud.DictTypeDal(auth.db).get_data(data_id, None, v_schema=schema))
|
return SuccessResponse(await crud.DictTypeDal(auth.db).get_data(data_id, None, v_schema=schema))
|
||||||
@ -74,12 +74,12 @@ async def get_dict_type(data_id: int, auth: Auth = Depends(AllUserAuth())):
|
|||||||
###########################################################
|
###########################################################
|
||||||
# 字典元素管理
|
# 字典元素管理
|
||||||
###########################################################
|
###########################################################
|
||||||
@app.post("/dict/details/", summary="创建字典元素")
|
@app.post("/dict/details", summary="创建字典元素")
|
||||||
async def create_dict_details(data: schemas.DictDetails, auth: Auth = Depends(AllUserAuth())):
|
async def create_dict_details(data: schemas.DictDetails, auth: Auth = Depends(AllUserAuth())):
|
||||||
return SuccessResponse(await crud.DictDetailsDal(auth.db).create_data(data=data))
|
return SuccessResponse(await crud.DictDetailsDal(auth.db).create_data(data=data))
|
||||||
|
|
||||||
|
|
||||||
@app.get("/dict/details/", summary="获取单个字典类型下的字典元素列表,分页")
|
@app.get("/dict/details", summary="获取单个字典类型下的字典元素列表,分页")
|
||||||
async def get_dict_details(params: DictDetailParams = Depends(), auth: Auth = Depends(AllUserAuth())):
|
async def get_dict_details(params: DictDetailParams = Depends(), auth: Auth = Depends(AllUserAuth())):
|
||||||
if not params.dict_type_id:
|
if not params.dict_type_id:
|
||||||
return ErrorResponse(msg="未获取到字典类型!")
|
return ErrorResponse(msg="未获取到字典类型!")
|
||||||
@ -88,18 +88,18 @@ async def get_dict_details(params: DictDetailParams = Depends(), auth: Auth = De
|
|||||||
return SuccessResponse(datas, count=count)
|
return SuccessResponse(datas, count=count)
|
||||||
|
|
||||||
|
|
||||||
@app.delete("/dict/details/", summary="批量删除字典元素", description="硬删除")
|
@app.delete("/dict/details", summary="批量删除字典元素", description="硬删除")
|
||||||
async def delete_dict_details(ids: IdList = Depends(), auth: Auth = Depends(AllUserAuth())):
|
async def delete_dict_details(ids: IdList = Depends(), auth: Auth = Depends(AllUserAuth())):
|
||||||
await crud.DictDetailsDal(auth.db).delete_datas(ids.ids, v_soft=False)
|
await crud.DictDetailsDal(auth.db).delete_datas(ids.ids, v_soft=False)
|
||||||
return SuccessResponse("删除成功")
|
return SuccessResponse("删除成功")
|
||||||
|
|
||||||
|
|
||||||
@app.put("/dict/details/{data_id}/", summary="更新字典元素")
|
@app.put("/dict/details/{data_id}", summary="更新字典元素")
|
||||||
async def put_dict_details(data_id: int, data: schemas.DictDetails, auth: Auth = Depends(AllUserAuth())):
|
async def put_dict_details(data_id: int, data: schemas.DictDetails, auth: Auth = Depends(AllUserAuth())):
|
||||||
return SuccessResponse(await crud.DictDetailsDal(auth.db).put_data(data_id, data))
|
return SuccessResponse(await crud.DictDetailsDal(auth.db).put_data(data_id, data))
|
||||||
|
|
||||||
|
|
||||||
@app.get("/dict/details/{data_id}/", summary="获取字典元素详情")
|
@app.get("/dict/details/{data_id}", summary="获取字典元素详情")
|
||||||
async def get_dict_detail(data_id: int, auth: Auth = Depends(AllUserAuth())):
|
async def get_dict_detail(data_id: int, auth: Auth = Depends(AllUserAuth())):
|
||||||
schema = schemas.DictDetailsSimpleOut
|
schema = schemas.DictDetailsSimpleOut
|
||||||
return SuccessResponse(await crud.DictDetailsDal(auth.db).get_data(data_id, None, v_schema=schema))
|
return SuccessResponse(await crud.DictDetailsDal(auth.db).get_data(data_id, None, v_schema=schema))
|
||||||
@ -108,7 +108,7 @@ async def get_dict_detail(data_id: int, auth: Auth = Depends(AllUserAuth())):
|
|||||||
###########################################################
|
###########################################################
|
||||||
# 文件上传管理
|
# 文件上传管理
|
||||||
###########################################################
|
###########################################################
|
||||||
@app.post("/upload/image/to/oss/", summary="上传图片到阿里云OSS")
|
@app.post("/upload/image/to/oss", summary="上传图片到阿里云OSS")
|
||||||
async def upload_image_to_oss(file: UploadFile, path: str = Form(...)):
|
async def upload_image_to_oss(file: UploadFile, path: str = Form(...)):
|
||||||
result = await AliyunOSS(BucketConf(**ALIYUN_OSS)).upload_image(path, file)
|
result = await AliyunOSS(BucketConf(**ALIYUN_OSS)).upload_image(path, file)
|
||||||
if not result:
|
if not result:
|
||||||
@ -116,7 +116,7 @@ async def upload_image_to_oss(file: UploadFile, path: str = Form(...)):
|
|||||||
return SuccessResponse(result)
|
return SuccessResponse(result)
|
||||||
|
|
||||||
|
|
||||||
@app.post("/upload/image/to/local/", summary="上传图片到本地")
|
@app.post("/upload/image/to/local", summary="上传图片到本地")
|
||||||
async def upload_image_to_local(file: UploadFile, path: str = Form(...)):
|
async def upload_image_to_local(file: UploadFile, path: str = Form(...)):
|
||||||
manage = FileManage(file, path)
|
manage = FileManage(file, path)
|
||||||
path = await manage.save_image_local()
|
path = await manage.save_image_local()
|
||||||
@ -126,7 +126,7 @@ async def upload_image_to_local(file: UploadFile, path: str = Form(...)):
|
|||||||
###########################################################
|
###########################################################
|
||||||
# 短信服务管理
|
# 短信服务管理
|
||||||
###########################################################
|
###########################################################
|
||||||
@app.post("/sms/send/", summary="发送短信验证码(阿里云服务)")
|
@app.post("/sms/send", summary="发送短信验证码(阿里云服务)")
|
||||||
async def sms_send(telephone: str, rd: Redis = Depends(redis_getter)):
|
async def sms_send(telephone: str, rd: Redis = Depends(redis_getter)):
|
||||||
sms = AliyunSMS(rd, telephone)
|
sms = AliyunSMS(rd, telephone)
|
||||||
return SuccessResponse(await sms.main_async(AliyunSMS.Scene.login))
|
return SuccessResponse(await sms.main_async(AliyunSMS.Scene.login))
|
||||||
@ -135,31 +135,31 @@ async def sms_send(telephone: str, rd: Redis = Depends(redis_getter)):
|
|||||||
###########################################################
|
###########################################################
|
||||||
# 系统配置管理
|
# 系统配置管理
|
||||||
###########################################################
|
###########################################################
|
||||||
@app.get("/settings/tabs/", summary="获取系统配置标签列表")
|
@app.get("/settings/tabs", summary="获取系统配置标签列表")
|
||||||
async def get_settings_tabs(classify: str, auth: Auth = Depends(FullAdminAuth())):
|
async def get_settings_tabs(classify: str, auth: Auth = Depends(FullAdminAuth())):
|
||||||
return SuccessResponse(await crud.SettingsTabDal(auth.db).get_datas(limit=0, classify=classify))
|
return SuccessResponse(await crud.SettingsTabDal(auth.db).get_datas(limit=0, classify=classify))
|
||||||
|
|
||||||
|
|
||||||
@app.get("/settings/tabs/values/", summary="获取系统配置标签下的信息")
|
@app.get("/settings/tabs/values", summary="获取系统配置标签下的信息")
|
||||||
async def get_settings_tabs_values(tab_id: int, auth: Auth = Depends(FullAdminAuth())):
|
async def get_settings_tabs_values(tab_id: int, auth: Auth = Depends(FullAdminAuth())):
|
||||||
return SuccessResponse(await crud.SettingsDal(auth.db).get_tab_values(tab_id=tab_id))
|
return SuccessResponse(await crud.SettingsDal(auth.db).get_tab_values(tab_id=tab_id))
|
||||||
|
|
||||||
|
|
||||||
@app.put("/settings/tabs/values/", summary="更新系统配置信息")
|
@app.put("/settings/tabs/values", summary="更新系统配置信息")
|
||||||
async def put_settings_tabs_values(datas: dict = Body(...), auth: Auth = Depends(FullAdminAuth()), rd: Redis = Depends(redis_getter)):
|
async def put_settings_tabs_values(datas: dict = Body(...), auth: Auth = Depends(FullAdminAuth()), rd: Redis = Depends(redis_getter)):
|
||||||
return SuccessResponse(await crud.SettingsDal(auth.db).update_datas(datas, rd))
|
return SuccessResponse(await crud.SettingsDal(auth.db).update_datas(datas, rd))
|
||||||
|
|
||||||
|
|
||||||
@app.get("/settings/base/config/", summary="获取系统基础配置", description="每次进入系统中时使用")
|
@app.get("/settings/base/config", summary="获取系统基础配置", description="每次进入系统中时使用")
|
||||||
async def get_setting_base_config(db: AsyncSession = Depends(db_getter)):
|
async def get_setting_base_config(db: AsyncSession = Depends(db_getter)):
|
||||||
return SuccessResponse(await crud.SettingsDal(db).get_base_config())
|
return SuccessResponse(await crud.SettingsDal(db).get_base_config())
|
||||||
|
|
||||||
|
|
||||||
@app.get("/settings/privacy/", summary="获取隐私协议")
|
@app.get("/settings/privacy", summary="获取隐私协议")
|
||||||
async def get_settings_privacy(auth: Auth = Depends(FullAdminAuth())):
|
async def get_settings_privacy(auth: Auth = Depends(FullAdminAuth())):
|
||||||
return SuccessResponse((await crud.SettingsDal(auth.db).get_data(config_key="web_privacy")).config_value)
|
return SuccessResponse((await crud.SettingsDal(auth.db).get_data(config_key="web_privacy")).config_value)
|
||||||
|
|
||||||
|
|
||||||
@app.get("/settings/agreement/", summary="获取用户协议")
|
@app.get("/settings/agreement", summary="获取用户协议")
|
||||||
async def get_settings_agreement(auth: Auth = Depends(FullAdminAuth())):
|
async def get_settings_agreement(auth: Auth = Depends(FullAdminAuth())):
|
||||||
return SuccessResponse((await crud.SettingsDal(auth.db).get_data(config_key="web_agreement")).config_value)
|
return SuccessResponse((await crud.SettingsDal(auth.db).get_data(config_key="web_agreement")).config_value)
|
||||||
|
@ -19,7 +19,7 @@ app = APIRouter()
|
|||||||
###########################################################
|
###########################################################
|
||||||
# 工作区管理
|
# 工作区管理
|
||||||
###########################################################
|
###########################################################
|
||||||
@app.get("/total/", summary="获取统计")
|
@app.get("/total", summary="获取统计")
|
||||||
async def get_total(auth: Auth = Depends(AllUserAuth())):
|
async def get_total(auth: Auth = Depends(AllUserAuth())):
|
||||||
data = {
|
data = {
|
||||||
"project": 40,
|
"project": 40,
|
||||||
@ -29,7 +29,7 @@ async def get_total(auth: Auth = Depends(AllUserAuth())):
|
|||||||
return SuccessResponse(data)
|
return SuccessResponse(data)
|
||||||
|
|
||||||
|
|
||||||
@app.get("/project/", summary="获取项目")
|
@app.get("/project", summary="获取项目")
|
||||||
async def get_project():
|
async def get_project():
|
||||||
data = [
|
data = [
|
||||||
{
|
{
|
||||||
@ -84,7 +84,7 @@ async def get_project():
|
|||||||
return SuccessResponse(data)
|
return SuccessResponse(data)
|
||||||
|
|
||||||
|
|
||||||
@app.get("/dynamic/", summary="获取动态")
|
@app.get("/dynamic", summary="获取动态")
|
||||||
async def get_dynamic():
|
async def get_dynamic():
|
||||||
data = [
|
data = [
|
||||||
{
|
{
|
||||||
@ -99,7 +99,7 @@ async def get_dynamic():
|
|||||||
return SuccessResponse(data)
|
return SuccessResponse(data)
|
||||||
|
|
||||||
|
|
||||||
@app.get("/team/", summary="获取团队信息")
|
@app.get("/team", summary="获取团队信息")
|
||||||
async def get_team():
|
async def get_team():
|
||||||
data = [
|
data = [
|
||||||
{
|
{
|
||||||
@ -130,7 +130,7 @@ async def get_team():
|
|||||||
return SuccessResponse(data)
|
return SuccessResponse(data)
|
||||||
|
|
||||||
|
|
||||||
@app.get("/shortcuts/", summary="获取快捷操作")
|
@app.get("/shortcuts", summary="获取快捷操作")
|
||||||
async def get_shortcuts():
|
async def get_shortcuts():
|
||||||
data = [
|
data = [
|
||||||
{
|
{
|
||||||
|
@ -31,7 +31,6 @@ def create_async_engine_session(database_url: str):
|
|||||||
pool_timeout=20, # 池中没有连接最多等待的时间,否则报错
|
pool_timeout=20, # 池中没有连接最多等待的时间,否则报错
|
||||||
pool_recycle=-1 # 多久之后对线程池中的线程进行一次连接的回收(重置)
|
pool_recycle=-1 # 多久之后对线程池中的线程进行一次连接的回收(重置)
|
||||||
|
|
||||||
:param database_type: 数据库类型
|
|
||||||
:param database_url: 数据库地址
|
:param database_url: 数据库地址
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
|
@ -47,7 +47,7 @@ def register_exception(app: FastAPI):
|
|||||||
print(exc.desc)
|
print(exc.desc)
|
||||||
print(exc.msg)
|
print(exc.msg)
|
||||||
return JSONResponse(
|
return JSONResponse(
|
||||||
status_code=200,
|
status_code=exc.status_code,
|
||||||
content={"message": exc.msg, "code": exc.code},
|
content={"message": exc.msg, "code": exc.code},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ idna==3.4
|
|||||||
importlib-metadata==5.0.0
|
importlib-metadata==5.0.0
|
||||||
importlib-resources==5.10.0
|
importlib-resources==5.10.0
|
||||||
jmespath==0.10.0
|
jmespath==0.10.0
|
||||||
loguru==0.6.0
|
loguru==0.7.0
|
||||||
Mako==1.2.4
|
Mako==1.2.4
|
||||||
MarkupSafe==2.1.1
|
MarkupSafe==2.1.1
|
||||||
motor==3.1.1
|
motor==3.1.1
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
# @desc : 缓存
|
# @desc : 缓存
|
||||||
|
|
||||||
from typing import List
|
from typing import List
|
||||||
from core import logger
|
from core.logger import logger
|
||||||
from core.database import db_getter
|
from core.database import db_getter
|
||||||
from apps.vadmin.system.crud import SettingsTabDal
|
from apps.vadmin.system.crud import SettingsTabDal
|
||||||
import json
|
import json
|
||||||
@ -18,7 +18,7 @@ from utils import status
|
|||||||
|
|
||||||
class Cache:
|
class Cache:
|
||||||
|
|
||||||
DEFAULT_TAB_NAMES = ["wx_server", "aliyun_sms", "aliyun_oss"]
|
DEFAULT_TAB_NAMES = ["wx_server", "aliyun_sms", "aliyun_oss", "web_email"]
|
||||||
|
|
||||||
def __init__(self, rd: Redis):
|
def __init__(self, rd: Redis):
|
||||||
self.rd = rd
|
self.rd = rd
|
||||||
|
@ -4,15 +4,17 @@
|
|||||||
# @File : file_manage.py
|
# @File : file_manage.py
|
||||||
# @IDE : PyCharm
|
# @IDE : PyCharm
|
||||||
# @desc : 保存图片到本地
|
# @desc : 保存图片到本地
|
||||||
|
import asyncio
|
||||||
import datetime
|
import datetime
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
from application.settings import TEMP_DIR, STATIC_ROOT, BASE_DIR, STATIC_URL, STATIC_DIR
|
from application.settings import TEMP_DIR, STATIC_ROOT, BASE_DIR, STATIC_URL, STATIC_DIR
|
||||||
from fastapi import UploadFile
|
from fastapi import UploadFile
|
||||||
import sys
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
from core.exception import CustomException
|
||||||
from utils.file.file_base import FileBase
|
from utils.file.file_base import FileBase
|
||||||
from aiopathlib import AsyncPath as Path
|
from aiopathlib import AsyncPath
|
||||||
import aioshutil
|
import aioshutil
|
||||||
|
|
||||||
|
|
||||||
@ -41,8 +43,7 @@ class FileManage(FileBase):
|
|||||||
path = self.path
|
path = self.path
|
||||||
if sys.platform == "win32":
|
if sys.platform == "win32":
|
||||||
path = self.path.replace("/", "\\")
|
path = self.path.replace("/", "\\")
|
||||||
# save_path = os.path.join(STATIC_ROOT, path)
|
save_path = AsyncPath(STATIC_ROOT) / path
|
||||||
save_path = Path(STATIC_ROOT) / path
|
|
||||||
if not await save_path.parent.exists():
|
if not await save_path.parent.exists():
|
||||||
await save_path.parent.mkdir(parents=True, exist_ok=True)
|
await save_path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
await save_path.write_bytes(await self.file.read())
|
await save_path.write_bytes(await self.file.read())
|
||||||
@ -52,21 +53,20 @@ class FileManage(FileBase):
|
|||||||
}
|
}
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def save_tmp_file(file: UploadFile):
|
async def save_tmp_file(file: UploadFile) -> str:
|
||||||
"""
|
"""
|
||||||
保存临时文件
|
保存临时文件
|
||||||
"""
|
"""
|
||||||
date = datetime.datetime.strftime(datetime.datetime.now(), "%Y%m%d")
|
date = datetime.datetime.strftime(datetime.datetime.now(), "%Y%m%d")
|
||||||
# file_dir = os.path.join(TEMP_DIR, date)
|
file_dir = AsyncPath(TEMP_DIR) / date
|
||||||
file_dir = Path(TEMP_DIR) / date
|
|
||||||
if not await file_dir.exists():
|
if not await file_dir.exists():
|
||||||
await file_dir.mkdir(parents=True, exist_ok=True)
|
await file_dir.mkdir(parents=True, exist_ok=True)
|
||||||
filename = file_dir / str(int(datetime.datetime.now().timestamp())) + file.filename
|
filename = file_dir / str(int(datetime.datetime.now().timestamp())) + file.filename
|
||||||
await filename.write_bytes(await self.file.read())
|
await filename.write_bytes(await file.read())
|
||||||
return str(filename)
|
return str(filename)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def copy(src: str, dst: str):
|
def copy(src: str, dst: str) -> None:
|
||||||
"""
|
"""
|
||||||
复制文件
|
复制文件
|
||||||
根目录为项目根目录,传过来的文件路径均为相对路径
|
根目录为项目根目录,传过来的文件路径均为相对路径
|
||||||
@ -79,25 +79,39 @@ class FileManage(FileBase):
|
|||||||
if sys.platform == "win32":
|
if sys.platform == "win32":
|
||||||
src = src.replace("/", "\\")
|
src = src.replace("/", "\\")
|
||||||
dst = dst.replace("/", "\\")
|
dst = dst.replace("/", "\\")
|
||||||
src = os.path.join(BASE_DIR, src)
|
src = Path(BASE_DIR) / src
|
||||||
if not os.path.exists(os.path.dirname(dst)):
|
dst = Path(dst)
|
||||||
os.mkdir(os.path.dirname(dst))
|
if not src.exists():
|
||||||
|
raise CustomException("源文件不存在!")
|
||||||
|
if not dst.parent.exists():
|
||||||
|
dst.parent.mkdir(parents=True, exist_ok=True)
|
||||||
shutil.copyfile(src, dst)
|
shutil.copyfile(src, dst)
|
||||||
|
|
||||||
async def async_copy(src: str, dst: str):
|
@staticmethod
|
||||||
|
async def async_copy(src: str, dst: str) -> None:
|
||||||
|
"""
|
||||||
|
异步复制文件
|
||||||
|
根目录为项目根目录,传过来的文件路径均为相对路径
|
||||||
|
|
||||||
|
:param src: 原始文件
|
||||||
|
:param dst: 目标路径。绝对路径
|
||||||
|
"""
|
||||||
if src[0] == "/":
|
if src[0] == "/":
|
||||||
src = src.lstrip("/")
|
src = src.lstrip("/")
|
||||||
if sys.platform == "win32":
|
if sys.platform == "win32":
|
||||||
src = src.replace("/", "\\")
|
src = src.replace("/", "\\")
|
||||||
dst = dst.replace("/", "\\")
|
dst = dst.replace("/", "\\")
|
||||||
src = Path(BASE_DIR) / src
|
src = AsyncPath(BASE_DIR) / src
|
||||||
dst = Path(dst)
|
if not await src.exists():
|
||||||
|
raise CustomException("源文件不存在!")
|
||||||
|
dst = AsyncPath(dst)
|
||||||
if not await dst.parent.exists():
|
if not await dst.parent.exists():
|
||||||
await dst.parent.mkdir(parents=True, exist_ok=True)
|
await dst.parent.mkdir(parents=True, exist_ok=True)
|
||||||
await aioshutil.copyfile(src, dst)
|
await aioshutil.copyfile(src, dst)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
# src = r"D:\ktianc\private\vv-reserve\reserve-api\static\system\2022-12-07\16703958210ab33912.ico"
|
_src = r"D:\programming\ktianc\project\kinit-pro\kinit-api\static\system\favicon.ico"
|
||||||
# dst = r"D:\ktianc\private\vv-reserve\reserve-api\static\system\favicon.ico"
|
_dst = r"D:\programming\ktianc\project\kinit-pro\kinit-api\static\system\2022-12-07\16703958210ab33912.ico"
|
||||||
# shutil.copyfile(src, dst)
|
asyncio.run(FileManage.async_copy(_src, _dst))
|
||||||
pass
|
# FileManage.copy(_src, _dst)
|
||||||
|
@ -8,18 +8,18 @@ export function login(telephone, password) {
|
|||||||
method: '0',
|
method: '0',
|
||||||
platform: '1'
|
platform: '1'
|
||||||
}
|
}
|
||||||
return request.post('/auth/login/', data)
|
return request.post('/auth/login', data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取用户详细信息
|
// 获取用户详细信息
|
||||||
export function getInfo() {
|
export function getInfo() {
|
||||||
return request.get('/vadmin/auth/user/admin/current/info/')
|
return request.get('/vadmin/auth/user/admin/current/info')
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新用户openid
|
// 更新用户openid
|
||||||
export function setUserOpenid(code) {
|
export function setUserOpenid(code) {
|
||||||
const params = { code }
|
const params = { code }
|
||||||
return request.put('/vadmin/auth/users/wx/server/openid/', {}, { params: params })
|
return request.put('/vadmin/auth/users/wx/server/openid', {}, { params: params })
|
||||||
}
|
}
|
||||||
|
|
||||||
// 使用微信一键登录
|
// 使用微信一键登录
|
||||||
@ -29,5 +29,5 @@ export function wxCodeLogin(code) {
|
|||||||
method: '2',
|
method: '2',
|
||||||
platform: '1'
|
platform: '1'
|
||||||
}
|
}
|
||||||
return request.post('/auth/wx/login/', data)
|
return request.post('/auth/wx/login', data)
|
||||||
}
|
}
|
||||||
|
@ -2,17 +2,17 @@ import request from '@/common/request/request'
|
|||||||
|
|
||||||
// 更新当前用户基本信息
|
// 更新当前用户基本信息
|
||||||
export function updateCurrentUser(data) {
|
export function updateCurrentUser(data) {
|
||||||
return request.post('/vadmin/auth/user/current/update/info/', data)
|
return request.post('/vadmin/auth/user/current/update/info', data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 重置当前用户密码
|
// 重置当前用户密码
|
||||||
export function postCurrentUserResetPassword(data) {
|
export function postCurrentUserResetPassword(data) {
|
||||||
return request.post('/vadmin/auth/user/current/reset/password/', data)
|
return request.post('/vadmin/auth/user/current/reset/password', data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新当前用户头像
|
// 更新当前用户头像
|
||||||
export function postCurrentUserUploadAvatar(filePath) {
|
export function postCurrentUserUploadAvatar(filePath) {
|
||||||
return request.upload('/vadmin/auth/user/current/update/avatar/', {
|
return request.upload('/vadmin/auth/user/current/update/avatar', {
|
||||||
filePath: filePath,
|
filePath: filePath,
|
||||||
name: 'file'
|
name: 'file'
|
||||||
})
|
})
|
||||||
|
@ -2,15 +2,15 @@ import request from '@/common/request/request.js'
|
|||||||
|
|
||||||
// 获取平台中的常见问题类别列表
|
// 获取平台中的常见问题类别列表
|
||||||
export function getIssueCategoryList() {
|
export function getIssueCategoryList() {
|
||||||
return request.get('/vadmin/help/issue/categorys/platform/1/')
|
return request.get('/vadmin/help/issue/categorys/platform/1')
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取问题详情
|
// 获取问题详情
|
||||||
export function getIssue(dataId) {
|
export function getIssue(dataId) {
|
||||||
return request.get(`/vadmin/help/issues/${dataId}/`)
|
return request.get(`/vadmin/help/issues/${dataId}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新常见问题查看次数+1
|
// 更新常见问题查看次数+1
|
||||||
export function updateIssueAddViewNumber(dataId) {
|
export function updateIssueAddViewNumber(dataId) {
|
||||||
return request.get(`/vadmin/help/issues/add/view/number/${dataId}/`)
|
return request.get(`/vadmin/help/issues/add/view/number/${dataId}`)
|
||||||
}
|
}
|
||||||
|
@ -2,5 +2,5 @@ import request from '@/common/request/request.js'
|
|||||||
|
|
||||||
// 获取多个字典类型下的字典元素列表
|
// 获取多个字典类型下的字典元素列表
|
||||||
export function getDictTypeDetailsApi(data) {
|
export function getDictTypeDetailsApi(data) {
|
||||||
return request.post('/vadmin/system/dict/types/details/', data)
|
return request.post('/vadmin/system/dict/types/details', data)
|
||||||
}
|
}
|
||||||
|
@ -2,5 +2,5 @@ import request from '@/common/request/request'
|
|||||||
|
|
||||||
// 获取系统基本配置
|
// 获取系统基本配置
|
||||||
export function getSystemBaseConfigApi() {
|
export function getSystemBaseConfigApi() {
|
||||||
return request.get('/vadmin/system/settings/base/config/')
|
return request.get('/vadmin/system/settings/base/config')
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user