diff --git a/backend/dvadmin/utils/viewset.py b/backend/dvadmin/utils/viewset.py index 8a7221d..0d6daa0 100644 --- a/backend/dvadmin/utils/viewset.py +++ b/backend/dvadmin/utils/viewset.py @@ -20,7 +20,8 @@ from dvadmin.utils.json_response import SuccessResponse, ErrorResponse, DetailRe from dvadmin.utils.permission import CustomPermission from django_restql.mixins import QueryArgumentsMixin -class CustomModelViewSet(ModelViewSet,ImportSerializerMixin,ExportSerializerMixin,QueryArgumentsMixin): + +class CustomModelViewSet(ModelViewSet, ImportSerializerMixin, ExportSerializerMixin, QueryArgumentsMixin): """ 自定义的ModelViewSet: 统一标准的返回格式;新增,查询,修改可使用不同序列化器 @@ -51,7 +52,6 @@ class CustomModelViewSet(ModelViewSet,ImportSerializerMixin,ExportSerializerMixi return self.values_queryset return super().get_queryset() - def get_serializer_class(self): action_serializer_name = f"{self.action}_serializer_class" action_serializer_class = getattr(self, action_serializer_name, None) @@ -80,7 +80,7 @@ class CustomModelViewSet(ModelViewSet,ImportSerializerMixin,ExportSerializerMixi page = self.paginate_queryset(queryset) if page is not None: serializer = self.get_serializer(page, many=True, request=request) - return self.get_paginated_response(serializer.data) + return SuccessResponse(serializer.data, msg="获取成功") serializer = self.get_serializer(queryset, many=True, request=request) return SuccessResponse(data=serializer.data, msg="获取成功") @@ -107,17 +107,17 @@ class CustomModelViewSet(ModelViewSet,ImportSerializerMixin,ExportSerializerMixi instance.delete() return DetailResponse(data=[], msg="删除成功") + keys = openapi.Schema(description='主键列表', type=openapi.TYPE_ARRAY, items=openapi.TYPE_STRING) - keys = openapi.Schema(description='主键列表',type=openapi.TYPE_ARRAY,items=openapi.TYPE_STRING) @swagger_auto_schema(request_body=openapi.Schema( type=openapi.TYPE_OBJECT, required=['keys'], properties={'keys': keys} ), operation_summary='批量删除') - @action(methods=['delete'],detail=False) - def multiple_delete(self,request,*args,**kwargs): + @action(methods=['delete'], detail=False) + def multiple_delete(self, request, *args, **kwargs): request_data = request.data - keys = request_data.get('keys',None) + keys = request_data.get('keys', None) if keys: self.get_queryset().filter(id__in=keys).delete() return SuccessResponse(data=[], msg="删除成功") diff --git a/web/src/utils/service.ts b/web/src/utils/service.ts index 002fe37..04b936e 100644 --- a/web/src/utils/service.ts +++ b/web/src/utils/service.ts @@ -1,9 +1,10 @@ import axios from "axios"; import { get } from "lodash-es"; +// @ts-ignore import { errorLog, errorCreate } from "./tools.ts"; // import { env } from "/src/utils/util.env"; // import { useUserStore } from "../store/modules/user"; -import { Session } from '/@/utils/storage'; +import { Local, Session } from '/@/utils/storage'; /** * @description 创建请求实例 */ @@ -37,6 +38,13 @@ function createService() { } else { // 有 code 代表这是一个后端接口 可以进行进一步的判断 switch (code) { + case 401: + Local.clear(); + Session.clear(); + window.location.reload(); + dataAxios.msg = "登录授权过期,请重新登录"; + errorCreate(`${dataAxios.msg}: ${response.config.url}`); + break case 2000: // @ts-ignore if (response.config.unpack === false) { diff --git a/web/src/views/system/user/api.ts b/web/src/views/system/user/api.ts new file mode 100644 index 0000000..dfdb765 --- /dev/null +++ b/web/src/views/system/user/api.ts @@ -0,0 +1,41 @@ +import { request } from '/@/utils/service'; +import { PageQuery, AddReq, DelReq, EditReq, InfoReq } from '@fast-crud/fast-crud'; + +export const apiPrefix = '/api/system/user/'; +export function GetList(query: PageQuery) { + return request({ + url: apiPrefix, + method: 'get', + data: query, + }); +} +export function GetObj(id: InfoReq) { + return request({ + url: apiPrefix + id, + method: 'get', + }); +} + +export function AddObj(obj: AddReq) { + return request({ + url: apiPrefix, + method: 'post', + data: obj, + }); +} + +export function UpdateObj(obj: EditReq) { + return request({ + url: apiPrefix + obj.id + '/', + method: 'put', + data: obj, + }); +} + +export function DelObj(id: DelReq) { + return request({ + url: apiPrefix + id + '/', + method: 'delete', + data: { id }, + }); +} diff --git a/web/src/views/system/user/component/addUser.vue b/web/src/views/system/user/component/addUser.vue deleted file mode 100644 index 4a78153..0000000 --- a/web/src/views/system/user/component/addUser.vue +++ /dev/null @@ -1,200 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - {{ data.deptName }} - ({{ data.children.length }}) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 取 消 - 新 增 - - - - - - - diff --git a/web/src/views/system/user/component/editUser.vue b/web/src/views/system/user/component/editUser.vue deleted file mode 100644 index b7a0793..0000000 --- a/web/src/views/system/user/component/editUser.vue +++ /dev/null @@ -1,202 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - {{ data.deptName }} - ({{ data.children.length }}) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 取 消 - 修 改 - - - - - - - diff --git a/web/src/views/system/user/crud.tsx b/web/src/views/system/user/crud.tsx new file mode 100644 index 0000000..ec1819e --- /dev/null +++ b/web/src/views/system/user/crud.tsx @@ -0,0 +1,323 @@ +import * as api from "./api"; +import { dict, PageQuery, AddReq, DelReq, EditReq, CrudExpose, CrudOptions, } from "@fast-crud/fast-crud"; +import { request } from "/@/utils/service"; +import { dictionary } from "/@/utils/dictionary"; +interface CreateCrudOptionsTypes { + crudOptions: CrudOptions; +} + +export const createCrudOptions = function ({ crudExpose }: { crudExpose: CrudExpose }): CreateCrudOptionsTypes { + const pageRequest = async (query: PageQuery) => { + return await api.GetList(query); + }; + const editRequest = async ({ form, row }: EditReq) => { + form.id = row.id; + return await api.UpdateObj(form); + }; + const delRequest = async ({ row }: DelReq) => { + return await api.DelObj(row.id); + }; + const addRequest = async ({ form }: AddReq) => { + return await api.AddObj(form); + }; + return { + crudOptions: { + request: { + pageRequest, + addRequest, + editRequest, + delRequest + }, + rowHandle: { + width: 400, + buttons: { + orderExample: { + text: "重置密码", + click: () => { + console.log("reset password") + } + } + }, + + }, + columns: { + _index: { + title: '序号', + form: { show: false }, + column: { + //type: 'index', + align: 'center', + width: '70px', + columnSetDisabled: true, //禁止在列设置中选择 + formatter: (context) => { + //计算序号,你可以自定义计算规则,此处为翻页累加 + let index = context.index ?? 1; + let pagination = crudExpose.crudBinding.value.pagination; + return ((pagination.currentPage ?? 1) - 1) * pagination.pageSize + index + 1; + }, + }, + }, + search: { + title: '关键词', + column: { + show: false + }, + search: { + show: true, + component: { + props: { + clearable: true + }, + placeholder: '请输入关键词' + } + }, + form: { + show: false, + component: { + props: { + clearable: true + } + } + }, + }, + username: { + title: '账号', + search: { + show: true, + }, + minWidth: 100, + type: 'input', + form: { + rules: [ // 表单校验规则 + { + required: true, + message: '账号必填项' + } + ], + component: { + placeholder: '请输入账号' + }, + } + }, + password: { + title: '密码', + type: 'input', + column: { + show: false + }, + editForm: { + show: false + }, + form: { + rules: [ // 表单校验规则 + { + required: true, + message: '密码必填项' + } + ], + component: { + span: 12, + showPassword: true, + placeholder: '请输入密码' + }, + // value: vm.systemConfig('base.default_password'), + }, + /* valueResolve(row, key) { + if (row.password) { + row.password = vm.$md5(row.password) + } + } */ + }, + name: { + title: '姓名', + search: { + show: true, + }, + type: 'input', + form: { + rules: [ // 表单校验规则 + { + required: true, + message: '姓名必填项' + } + ], + component: { + span: 12, + placeholder: '请输入姓名' + }, + } + }, + dept: { + title: '部门', + search: { + disabled: true + }, + type: 'dict-tree', + dict: dict({ + isTree: true, + url: '/api/system/dept/all_dept/', + value: 'id', + label: 'name', + getData: async ({ url }: { url: string }) => { + return request({ + url: url, + }).then((ret: any) => { + return ret.data + }) + } + }), + form: { + component: { + filterable: true, + placeholder: '请选择角色', + props: { + props: { + value: "id", + label: "name", + } + } + }, + }, + }, + role: { + title: '角色', + search: { + disabled: true + }, + type: 'dict-tree', + dict: dict({ + url: '/api/system/role/', + value: 'id', + label: 'name', + isTree: true, + getData: async ({ url }: { url: string }) => { + return request({ + url: url, + params: { + page: 1, + limit: 10 + } + }).then((ret: any) => { + return ret.data + }) + } + }), + form: { + component: { + filterable: true, + placeholder: '请选择角色', + props: { + props: { + value: "id", + label: "name", + } + } + }, + } + }, + mobile: { + title: '手机号码', + search: { + show: true, + }, + type: 'input', + form: { + rules: [ + { + max: 20, + message: '请输入正确的手机号码', + trigger: 'blur' + }, + { + pattern: /^1[3-9]\d{9}$/, + message: '请输入正确的手机号码' + } + ], + component: { + placeholder: '请输入手机号码' + } + } + }, + email: { + title: '邮箱', + form: { + rules: [ + { + type: 'email', + message: '请输入正确的邮箱地址', + trigger: ['blur', 'change'] + } + ], + component: { + placeholder: '请输入邮箱' + } + } + }, + gender: { + title: '性别', + type: 'dict-radio', + dict: dict({ + data: dictionary('gender') + }), + form: { + value: 1, + component: { + span: 12 + } + }, + component: { props: { color: 'auto' } } // 自动染色 + }, + user_type: { + title: '用户类型', + search: { + show: true, + }, + type: 'dict-select', + dict: dict({ + data: dictionary('user_type') + }), + form: { + show: false, + value: 0, + component: { + span: 12 + } + } + }, + is_active: { + title: '状态', + search: { + show: true, + }, + type: 'dict-radio', + dict: dict({ + data: dictionary('button_status_bool') + }), + form: { + value: true, + component: { + span: 12 + } + } + }, + avatar: { + title: '头像', + type: 'avatar-cropper', + form: { + component: { + props: { + elProps: { // 与el-uploader 配置一致 + multiple: false, + limit: 1 // 限制5个文件 + }, + sizeLimit: 500 * 1024 // 不能超过限制 + }, + span: 24 + }, + helper: '限制文件大小不能超过500k' + } + } + } + } + }; +} diff --git a/web/src/views/system/user/index.vue b/web/src/views/system/user/index.vue index a120c59..1fa8634 100644 --- a/web/src/views/system/user/index.vue +++ b/web/src/views/system/user/index.vue @@ -1,177 +1,26 @@ - - - - - - - - - 查询 - - - - - - 新增用户 - - - - - - - - - - - - - 启用 - 禁用 - - - - - - - 修改 - 删除 - - - - - - - - - + + + -