diff --git a/backend/dvadmin/system/views/area.py b/backend/dvadmin/system/views/area.py
index 3a727282f92c5b3e72acf7f7f37d25d531857572..7a19eb076cd33cd95b7bbfa60592b4c34a284cda 100644
--- a/backend/dvadmin/system/views/area.py
+++ b/backend/dvadmin/system/views/area.py
@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
+import pypinyin
from django.db.models import Q
from rest_framework import serializers
@@ -15,6 +16,11 @@ class AreaSerializer(CustomModelSerializer):
"""
pcode_count = serializers.SerializerMethodField(read_only=True)
hasChild = serializers.SerializerMethodField()
+ pcode_info = serializers.SerializerMethodField()
+
+ def get_pcode_info(self, instance):
+ pcode = Area.objects.filter(code=instance.pcode_id).values("name", "code")
+ return pcode
def get_pcode_count(self, instance: Area):
return Area.objects.filter(pcode=instance).count()
@@ -36,6 +42,18 @@ class AreaCreateUpdateSerializer(CustomModelSerializer):
地区管理 创建/更新时的列化器
"""
+ def to_internal_value(self, data):
+ pinyin = ''.join([''.join(i) for i in pypinyin.pinyin(data["name"], style=pypinyin.NORMAL)])
+ data["level"] = 1
+ data["pinyin"] = pinyin
+ data["initials"] = pinyin[0].upper() if pinyin else "#"
+ pcode = data["pcode"] if 'pcode' in data else None
+ if pcode:
+ pcode = Area.objects.get(pk=pcode)
+ data["pcode"] = pcode.code
+ data["level"] = pcode.level + 1
+ return super().to_internal_value(data)
+
class Meta:
model = Area
fields = '__all__'
@@ -52,20 +70,28 @@ class AreaViewSet(CustomModelViewSet, FieldPermissionMixin):
"""
queryset = Area.objects.all()
serializer_class = AreaSerializer
+ create_serializer_class = AreaCreateUpdateSerializer
+ update_serializer_class = AreaCreateUpdateSerializer
extra_filter_class = []
- def get_queryset(self):
+ def list(self, request, *args, **kwargs):
self.request.query_params._mutable = True
params = self.request.query_params
- pcode = params.get('pcode', None)
- page = params.get('page', None)
- limit = params.get('limit', None)
- if page:
- del params['page']
- if limit:
- del params['limit']
- if params and pcode:
- queryset = self.queryset.filter(enable=True, pcode=pcode)
- else:
+ known_params = {'page', 'limit', 'pcode'}
+ # 使用集合操作检查是否有未知参数
+ other_params_exist = any(param not in known_params for param in params)
+ if other_params_exist:
queryset = self.queryset.filter(enable=True)
- return queryset
+ else:
+ pcode = params.get('pcode', None)
+ params['limit'] = 999
+ if params and pcode:
+ queryset = self.queryset.filter(enable=True, pcode=pcode)
+ else:
+ queryset = self.queryset.filter(enable=True, level=1)
+ 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)
+ serializer = self.get_serializer(queryset, many=True, request=request)
+ return SuccessResponse(data=serializer.data, msg="获取成功")
diff --git a/web/src/components/tableSelector/index.vue b/web/src/components/tableSelector/index.vue
index 7ad3cad84a0c5a695606a22a0642f41d621e97f2..8e8c91a9dc56db58087acc8c4ae2af414919c625 100644
--- a/web/src/components/tableSelector/index.vue
+++ b/web/src/components/tableSelector/index.vue
@@ -1,203 +1,211 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/web/src/utils/columnPermission.ts b/web/src/utils/columnPermission.ts
index aff14412b33fc0b6a44b5a85d96479bae9c33cd4..7ef06de0ba44a26f93a4a4b709697964ff3b4863 100644
--- a/web/src/utils/columnPermission.ts
+++ b/web/src/utils/columnPermission.ts
@@ -28,7 +28,6 @@ export const handleColumnPermission = async (func: Function, crudOptions: any,ex
if (excludeColumns.includes(item.field_name)) {
continue
} else if(item.field_name === col) {
- columns[col].column.show = item['is_query']
// 如果列表不可见,则禁止在列设置中选择
// 只有列表不可见,才修改列配置,这样才不影响默认的配置
if(!item['is_query']){
diff --git a/web/src/views/system/areas/crud.tsx b/web/src/views/system/areas/crud.tsx
index 01d1860253220ac98200c98e4a6446c79a5daab5..1a1e47b0c4f13b651617bc1e1689e61ca076a349 100644
--- a/web/src/views/system/areas/crud.tsx
+++ b/web/src/views/system/areas/crud.tsx
@@ -1,244 +1,202 @@
import * as api from './api';
-import {
- dict,
- UserPageQuery,
- AddReq,
- DelReq,
- EditReq,
- compute,
- CreateCrudOptionsProps,
- CreateCrudOptionsRet
-} from '@fast-crud/fast-crud';
-import {dictionary} from '/@/utils/dictionary';
-import {successMessage} from '/@/utils/message';
-import {auth} from "/@/utils/authFunction";
+import { dict, UserPageQuery, AddReq, DelReq, EditReq, compute, CreateCrudOptionsProps, CreateCrudOptionsRet } from '@fast-crud/fast-crud';
+import { dictionary } from '/@/utils/dictionary';
+import { successMessage } from '/@/utils/message';
+import { auth } from '/@/utils/authFunction';
+import tableSelector from '/@/components/tableSelector/index.vue';
+import { shallowRef } from 'vue';
-export const createCrudOptions = function ({crudExpose}: CreateCrudOptionsProps): CreateCrudOptionsRet {
- const pageRequest = async (query: UserPageQuery) => {
- 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);
- };
+export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet {
+ const pageRequest = async (query: UserPageQuery) => {
+ 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);
+ };
- /**
- * 懒加载
- * @param row
- * @returns {Promise}
- */
- const loadContentMethod = (tree: any, treeNode: any, resolve: Function) => {
- pageRequest({pcode: tree.code}).then((res: APIResponseData) => {
- resolve(res.data);
- });
- };
+ /**
+ * 懒加载
+ * @param row
+ * @returns {Promise}
+ */
+ const loadContentMethod = (tree: any, treeNode: any, resolve: Function) => {
+ pageRequest({ pcode: tree.code }).then((res: APIResponseData) => {
+ resolve(res.data);
+ });
+ };
- return {
- crudOptions: {
- request: {
- pageRequest,
- addRequest,
- editRequest,
- delRequest,
- },
- actionbar: {
- buttons: {
- add: {
- show: auth('area:Create'),
- }
- }
- },
- rowHandle: {
- //固定右侧
- fixed: 'right',
- width: 200,
- buttons: {
- view: {
- show: false,
- },
- edit: {
- iconRight: 'Edit',
- type: 'text',
- show: auth('area:Update')
- },
- remove: {
- iconRight: 'Delete',
- type: 'text',
- show: auth('area:Delete')
- },
- },
- },
- pagination: {
- show: false,
- },
- table: {
- rowKey: 'id',
- lazy: true,
- load: loadContentMethod,
- treeProps: {children: 'children', hasChildren: 'hasChild'},
- },
- columns: {
- _index: {
- title: '序号',
- form: {show: false},
- column: {
- type: 'index',
- align: 'center',
- width: '70px',
- columnSetDisabled: true, //禁止在列设置中选择
- },
- },
- // pcode: {
- // title: '父级地区',
- // show: false,
- // search: {
- // show: true,
- // },
- // type: 'dict-tree',
- // form: {
- // component: {
- // showAllLevels: false, // 仅显示最后一级
- // props: {
- // elProps: {
- // clearable: true,
- // showAllLevels: false, // 仅显示最后一级
- // props: {
- // checkStrictly: true, // 可以不需要选到最后一级
- // emitPath: false,
- // clearable: true,
- // },
- // },
- // },
- // },
- // },
- // },
- name: {
- title: '名称',
- search: {
- show: true,
- },
- treeNode: true,
- type: 'input',
- column: {
- minWidth: 120,
- },
- form: {
- rules: [
- // 表单校验规则
- {required: true, message: '名称必填项'},
- ],
- component: {
- placeholder: '请输入名称',
- },
- },
- },
- code: {
- title: '地区编码',
- search: {
- show: true,
- },
- type: 'input',
- column: {
- minWidth: 90,
- },
- form: {
- rules: [
- // 表单校验规则
- {required: true, message: '地区编码必填项'},
- ],
- component: {
- placeholder: '请输入地区编码',
- },
- },
- },
- pinyin: {
- title: '拼音',
- search: {
- disabled: true,
- },
- type: 'input',
- column: {
- minWidth: 120,
- },
- form: {
- rules: [
- // 表单校验规则
- {required: true, message: '拼音必填项'},
- ],
- component: {
- placeholder: '请输入拼音',
- },
- },
- },
- level: {
- title: '地区层级',
- search: {
- disabled: true,
- },
- type: 'input',
- column: {
- minWidth: 100,
- },
- form: {
- disabled: false,
- rules: [
- // 表单校验规则
- {required: true, message: '拼音必填项'},
- ],
- component: {
- placeholder: '请输入拼音',
- },
- },
- },
- initials: {
- title: '首字母',
- column: {
- minWidth: 100,
- },
- form: {
- rules: [
- // 表单校验规则
- {required: true, message: '首字母必填项'},
- ],
-
- component: {
- placeholder: '请输入首字母',
- },
- },
- },
- enable: {
- title: '是否启用',
- search: {
- show: true,
- },
- type: 'dict-radio',
- column: {
- minWidth: 90,
- component: {
- name: 'fs-dict-switch',
- activeText: '',
- inactiveText: '',
- style: '--el-switch-on-color: var(--el-color-primary); --el-switch-off-color: #dcdfe6',
- onChange: compute((context) => {
- return () => {
- api.UpdateObj(context.row).then((res: APIResponseData) => {
- successMessage(res.msg as string);
- });
- };
- }),
- },
- },
- dict: dict({
- data: dictionary('button_status_bool'),
- }),
- },
- },
- },
- };
+ return {
+ crudOptions: {
+ request: {
+ pageRequest,
+ addRequest,
+ editRequest,
+ delRequest,
+ },
+ actionbar: {
+ buttons: {
+ add: {
+ show: auth('area:Create'),
+ },
+ },
+ },
+ rowHandle: {
+ //固定右侧
+ fixed: 'right',
+ width: 200,
+ buttons: {
+ view: {
+ show: false,
+ },
+ edit: {
+ iconRight: 'Edit',
+ type: 'text',
+ show: auth('area:Update'),
+ },
+ remove: {
+ iconRight: 'Delete',
+ type: 'text',
+ show: auth('area:Delete'),
+ },
+ },
+ },
+ pagination: {
+ show: false,
+ },
+ table: {
+ rowKey: 'id',
+ lazy: true,
+ load: loadContentMethod,
+ treeProps: { children: 'children', hasChildren: 'hasChild' },
+ },
+ columns: {
+ _index: {
+ title: '序号',
+ form: { show: false },
+ column: {
+ type: 'index',
+ align: 'center',
+ width: '70px',
+ columnSetDisabled: true, //禁止在列设置中选择
+ },
+ },
+ name: {
+ title: '名称',
+ search: {
+ show: true,
+ },
+ treeNode: true,
+ type: 'input',
+ column: {
+ minWidth: 120,
+ },
+ form: {
+ rules: [
+ // 表单校验规则
+ { required: true, message: '名称必填项' },
+ ],
+ component: {
+ placeholder: '请输入名称',
+ },
+ },
+ },
+ pcode: {
+ title: '父级地区',
+ search: {
+ disabled: true,
+ },
+ width: 130,
+ type: 'table-selector',
+ form: {
+ component: {
+ name: shallowRef(tableSelector),
+ vModel: 'modelValue',
+ displayLabel: compute(({ row }) => {
+ if (row) {
+ return row.pcode_info;
+ }
+ return null;
+ }),
+ tableConfig: {
+ url: '/api/system/area/',
+ label: 'name',
+ value: 'id',
+ isTree: true,
+ isMultiple: false,
+ lazy: true,
+ load: loadContentMethod,
+ treeProps: { children: 'children', hasChildren: 'hasChild' },
+ columns: [
+ {
+ prop: 'name',
+ label: '地区',
+ width: 150,
+ },
+ {
+ prop: 'code',
+ label: '地区编码',
+ },
+ ],
+ },
+ },
+ },
+ column: {
+ show: false,
+ },
+ },
+ code: {
+ title: '地区编码',
+ search: {
+ show: true,
+ },
+ type: 'input',
+ column: {
+ minWidth: 90,
+ },
+ form: {
+ rules: [
+ // 表单校验规则
+ { required: true, message: '地区编码必填项' },
+ ],
+ component: {
+ placeholder: '请输入地区编码',
+ },
+ },
+ },
+ enable: {
+ title: '是否启用',
+ search: {
+ show: true,
+ },
+ type: 'dict-radio',
+ column: {
+ minWidth: 90,
+ component: {
+ name: 'fs-dict-switch',
+ activeText: '',
+ inactiveText: '',
+ style: '--el-switch-on-color: var(--el-color-primary); --el-switch-off-color: #dcdfe6',
+ onChange: compute((context) => {
+ return () => {
+ api.UpdateObj(context.row).then((res: APIResponseData) => {
+ successMessage(res.msg as string);
+ });
+ };
+ }),
+ },
+ },
+ dict: dict({
+ data: dictionary('button_status_bool'),
+ }),
+ },
+ },
+ },
+ };
};