新增:字典管理功能
parent
0118b8dca2
commit
8faeed2ff7
|
@ -30,6 +30,7 @@ from dvadmin.system.views.login import (
|
|||
ApiLogin,
|
||||
LogoutView,
|
||||
)
|
||||
from dvadmin.system.views.system_config import InitSettingsViewSet
|
||||
from dvadmin.utils.swagger import CustomOpenAPISchemaGenerator
|
||||
|
||||
schema_view = get_schema_view(
|
||||
|
@ -72,6 +73,7 @@ urlpatterns = (
|
|||
),
|
||||
path("api/captcha/", CaptchaView.as_view()),
|
||||
path("api/captcha/status/", CaptchaStatusView.as_view()),
|
||||
path("api/init/settings/", InitSettingsViewSet.as_view()),
|
||||
path("apiLogin/", ApiLogin.as_view()),
|
||||
]
|
||||
+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||
|
|
|
@ -34,7 +34,7 @@ TABLE_PREFIX = "sys_"
|
|||
# ================================================= #
|
||||
# ****************** 功能 启停 ******************* #
|
||||
# ================================================= #
|
||||
DEBUG = False
|
||||
DEBUG = True
|
||||
# 启动登录详细概略获取(通过调用api获取ip详细地址。如果是内网,关闭即可)
|
||||
ENABLE_LOGIN_ANALYSIS_LOG = True
|
||||
# 是否启用登录验证码,不需要可以设置为False,线上环境建议开启
|
||||
|
|
|
@ -166,13 +166,23 @@ class MenuButton(CoreModel):
|
|||
|
||||
|
||||
class Dictionary(CoreModel):
|
||||
code = models.CharField(max_length=100, blank=True, null=True, verbose_name="编码", help_text="编码")
|
||||
label = models.CharField(max_length=100, blank=True, null=True, verbose_name="显示名称", help_text="显示名称")
|
||||
value = models.CharField(max_length=100, blank=True, null=True, verbose_name="实际值", help_text="实际值")
|
||||
TYPE_LIST = (
|
||||
(0, 'text'),
|
||||
(1, 'number'),
|
||||
(2, 'date'),
|
||||
(3, 'datetime'),
|
||||
(4, 'time'),
|
||||
(5, 'files'),
|
||||
(6, 'boolean'),
|
||||
(7, 'images'),
|
||||
)
|
||||
label = models.CharField(max_length=100, blank=True, null=True, verbose_name="字典名称", help_text="字典名称")
|
||||
value = models.CharField(max_length=200, blank=True, null=True, verbose_name="字典编号", help_text="字典编号/实际值")
|
||||
parent = models.ForeignKey(to='self', related_name='sublist', db_constraint=False, on_delete=models.PROTECT,
|
||||
blank=True, null=True,
|
||||
verbose_name="父级", help_text="父级")
|
||||
status = models.BooleanField(default=True, blank=True, verbose_name="状态", help_text="状态")
|
||||
blank=True, null=True, verbose_name="父级", help_text="父级")
|
||||
type = models.IntegerField(choices=TYPE_LIST, default=0, verbose_name="数据值类型", help_text="数据值类型")
|
||||
is_value = models.BooleanField(default=False, verbose_name="是否为value值", help_text="是否为value值,用来做具体值存放")
|
||||
status = models.BooleanField(default=True, verbose_name="状态", help_text="状态")
|
||||
sort = models.IntegerField(default=1, verbose_name="显示排序", null=True, blank=True, help_text="显示排序")
|
||||
remark = models.CharField(max_length=2000, blank=True, null=True, verbose_name="备注", help_text="备注")
|
||||
|
||||
|
|
|
@ -6,12 +6,11 @@
|
|||
@Created on: 2021/6/3 003 0:30
|
||||
@Remark: 字典管理
|
||||
"""
|
||||
from rest_framework import serializers
|
||||
|
||||
from dvadmin.system.models import Dictionary
|
||||
from dvadmin.utils.json_response import SuccessResponse
|
||||
from dvadmin.utils.serializers import CustomModelSerializer
|
||||
from dvadmin.utils.viewset import CustomModelViewSet
|
||||
from rest_framework import serializers
|
||||
|
||||
|
||||
class DictionarySerializer(CustomModelSerializer):
|
||||
|
@ -42,16 +41,15 @@ class DictionaryTreeSerializer(CustomModelSerializer):
|
|||
children = serializers.SerializerMethodField(read_only=True)
|
||||
|
||||
def get_children(self, instance):
|
||||
queryset = Dictionary.objects.filter(parent=instance.id).filter(status=1)
|
||||
queryset = Dictionary.objects.filter(parent=instance.id).filter(status=1).values('label', 'value', 'type')
|
||||
if queryset:
|
||||
serializer = DictionaryTreeSerializer(queryset, many=True)
|
||||
return serializer.data
|
||||
return queryset
|
||||
else:
|
||||
return None
|
||||
return []
|
||||
|
||||
class Meta:
|
||||
model = Dictionary
|
||||
fields = "__all__"
|
||||
fields = ['id', 'value', 'children']
|
||||
read_only_fields = ["id"]
|
||||
|
||||
|
||||
|
@ -68,3 +66,15 @@ class DictionaryViewSet(CustomModelViewSet):
|
|||
serializer_class = DictionarySerializer
|
||||
extra_filter_backends = []
|
||||
search_fields = ['label']
|
||||
|
||||
def list(self, request, *args, **kwargs):
|
||||
dictionary_key = self.request.query_params.get('dictionary_key')
|
||||
if dictionary_key:
|
||||
if dictionary_key == 'all':
|
||||
queryset = self.queryset.filter(status=True, is_value=False)
|
||||
serializer = DictionaryTreeSerializer(queryset, many=True, request=request)
|
||||
data = serializer.data
|
||||
else:
|
||||
data = self.queryset.filter(parent__value=dictionary_key, status=True).values('label', 'value', 'type')
|
||||
return SuccessResponse(data=data, msg="获取成功")
|
||||
return super().list(request, *args, **kwargs)
|
||||
|
|
|
@ -10,9 +10,9 @@ import django_filters
|
|||
from django.db.models import Q
|
||||
from django_filters.rest_framework import BooleanFilter
|
||||
from rest_framework import serializers
|
||||
from rest_framework.views import APIView
|
||||
|
||||
from dvadmin.system.models import SystemConfig
|
||||
from dvadmin.utils.filters import DataLevelPermissionsFilter
|
||||
from dvadmin.utils.json_response import DetailResponse, SuccessResponse, ErrorResponse
|
||||
from dvadmin.utils.models import get_all_models_objects
|
||||
from dvadmin.utils.serializers import CustomModelSerializer
|
||||
|
@ -31,17 +31,17 @@ class SystemConfigCreateSerializer(CustomModelSerializer):
|
|||
fields = "__all__"
|
||||
read_only_fields = ["id"]
|
||||
|
||||
|
||||
def validate_key(self, value):
|
||||
"""
|
||||
验证key是否允许重复
|
||||
parent为空时不允许重复,反之允许
|
||||
"""
|
||||
instance = SystemConfig.objects.filter(key=value,parent__isnull=True).exists()
|
||||
instance = SystemConfig.objects.filter(key=value, parent__isnull=True).exists()
|
||||
if instance:
|
||||
raise CustomValidationError('已存在相同变量名')
|
||||
return value
|
||||
|
||||
|
||||
class SystemConfigSerializer(CustomModelSerializer):
|
||||
"""
|
||||
系统配置-序列化器
|
||||
|
@ -112,17 +112,9 @@ class SystemConfigFilter(django_filters.rest_framework.FilterSet):
|
|||
fields = ['id', 'parent', 'status', 'parent__isnull']
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class SystemConfigViewSet(CustomModelViewSet):
|
||||
"""
|
||||
系统配置接口
|
||||
list:查询
|
||||
create:新增
|
||||
update:修改
|
||||
retrieve:详情
|
||||
destroy:删除
|
||||
"""
|
||||
queryset = SystemConfig.objects.order_by('sort', 'create_datetime')
|
||||
serializer_class = SystemConfigChinldernSerializer
|
||||
|
@ -152,7 +144,7 @@ class SystemConfigViewSet(CustomModelViewSet):
|
|||
res = [ele.get('table') for ele in get_all_models_objects().values()]
|
||||
return DetailResponse(msg="获取成功", data=res)
|
||||
|
||||
def get_table_data(self, request,pk):
|
||||
def get_table_data(self, request, pk):
|
||||
"""
|
||||
动态获取关联表的数据
|
||||
"""
|
||||
|
@ -162,7 +154,7 @@ class SystemConfigViewSet(CustomModelViewSet):
|
|||
setting = instance.setting
|
||||
if setting is None:
|
||||
return ErrorResponse(msg="查询出错了~")
|
||||
table = setting.get('table') #获取model名
|
||||
table = setting.get('table') # 获取model名
|
||||
model = get_all_models_objects(table).get("object", {})
|
||||
# 自己判断一下不存在
|
||||
queryset = model.objects.values()
|
||||
|
@ -181,15 +173,14 @@ class SystemConfigViewSet(CustomModelViewSet):
|
|||
return self.get_paginated_response(queryset)
|
||||
return SuccessResponse(msg="获取成功", data=queryset, total=len(queryset))
|
||||
|
||||
|
||||
def get_relation_info(self,request):
|
||||
def get_relation_info(self, request):
|
||||
"""
|
||||
查询关联的模板信息
|
||||
"""
|
||||
body = request.query_params
|
||||
var_name = body.get('varName',None)
|
||||
table = body.get('table',None)
|
||||
instance = SystemConfig.objects.filter(key=var_name,setting__table=table).first()
|
||||
var_name = body.get('varName', None)
|
||||
table = body.get('table', None)
|
||||
instance = SystemConfig.objects.filter(key=var_name, setting__table=table).first()
|
||||
if instance is None:
|
||||
return ErrorResponse(msg="未获取到关联信息")
|
||||
relation_id = body.get('relationIds', None)
|
||||
|
@ -204,4 +195,23 @@ class SystemConfigViewSet(CustomModelViewSet):
|
|||
if queryset is None:
|
||||
return ErrorResponse(msg="未获取到关联信息")
|
||||
serializer = SystemConfigChinldernSerializer(queryset.parent)
|
||||
return DetailResponse(msg="查询成功",data=serializer.data)
|
||||
return DetailResponse(msg="查询成功", data=serializer.data)
|
||||
|
||||
|
||||
class InitSettingsViewSet(APIView):
|
||||
"""
|
||||
获取初始化配置
|
||||
"""
|
||||
authentication_classes = []
|
||||
permission_classes = []
|
||||
|
||||
def get(self, request):
|
||||
data = {
|
||||
"site_name": "DVAdmin", # 网站名称
|
||||
"site_logo": "", # 网站logo地址
|
||||
"login_background": "", # 登录页背景图
|
||||
"login_banner": "", # 登录页Banner图
|
||||
"copyright": "2021-2022 django-vue-admin.com 版权所有", # 版权
|
||||
"keep_record": "晋ICP备18005113号-3" # 备案
|
||||
}
|
||||
return DetailResponse(data=data)
|
||||
|
|
|
@ -69,3 +69,52 @@
|
|||
*::-webkit-scrollbar-thumb:hover {
|
||||
background-color: #bbb;
|
||||
}
|
||||
.el-drawer__header{
|
||||
border-bottom: 1px solid #e8e8e8;
|
||||
border-radius: 4px 4px 0 0;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
/*设置抽屉样式*/
|
||||
.el-drawer__header span{
|
||||
margin: 0;
|
||||
color: rgba(0,0,0,.85);
|
||||
font-weight: 500;
|
||||
font-size: 16px;
|
||||
line-height: 22px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.el-drawer__close-btn{
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
z-index: 10;
|
||||
display: block;
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
padding: 0;
|
||||
color: rgba(0,0,0,.45);
|
||||
font-weight: 700;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
line-height: 56px;
|
||||
text-align: center;
|
||||
text-transform: none;
|
||||
text-decoration: none;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
outline: 0;
|
||||
cursor: pointer;
|
||||
transition: color .3s;
|
||||
text-rendering: auto;
|
||||
}
|
||||
.el-dialog__close{
|
||||
font-weight: 700;
|
||||
font-size: 16px;
|
||||
}
|
||||
.el-drawer__body .d2-container-full {
|
||||
border: none!important;
|
||||
/* border-top: none; */
|
||||
/* border-bottom: none; */
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
import { request } from '@/api/service'
|
||||
|
||||
export const urlPrefix = '/api/system/dictionary/'
|
||||
|
||||
// 系统配置
|
||||
export default {
|
||||
namespaced: true,
|
||||
state: {
|
||||
data: {} // 字典值集合
|
||||
},
|
||||
actions: {
|
||||
/**
|
||||
* @description 本地加载配置
|
||||
* @param {Object} context
|
||||
* @param {String} key
|
||||
*/
|
||||
async load ({ state, dispatch, commit }, key = 'all') {
|
||||
const query = { dictionary_key: key }
|
||||
request({
|
||||
url: urlPrefix,
|
||||
params: query,
|
||||
method: 'get'
|
||||
}).then(async res => {
|
||||
// store 赋值
|
||||
var newData = {}
|
||||
if (key === 'all') {
|
||||
res.data.data.map(data => {
|
||||
data.children.map((children, index) => {
|
||||
console.log(children.type)
|
||||
switch (children.type) {
|
||||
case 1:
|
||||
children.value = Number(children.value)
|
||||
break
|
||||
case 6:
|
||||
children.value = children.value === 'true'
|
||||
break
|
||||
}
|
||||
})
|
||||
newData[data.value] = data.children
|
||||
})
|
||||
console.log(11, newData)
|
||||
state.data = newData
|
||||
} else {
|
||||
state.data = res.data.data[key]
|
||||
}
|
||||
})
|
||||
}
|
||||
/**
|
||||
* @description 获取配置
|
||||
* @param {Object} state state
|
||||
* @param {Object} dispatch dispatch
|
||||
* @param {String} key 字典值
|
||||
* @param {String} isCache 是否缓存
|
||||
*/
|
||||
},
|
||||
mutations: {
|
||||
/**
|
||||
* @description 设置配置
|
||||
* @param {Object} state state
|
||||
* @param {Boolean} key active
|
||||
* @param {Boolean} value active
|
||||
*/
|
||||
async set (state, key, value) {
|
||||
state.data[key] = value
|
||||
},
|
||||
/**
|
||||
* @description 获取配置
|
||||
* @param {Object} state state
|
||||
* @param {Boolean} key active
|
||||
*/
|
||||
async get (state, key) {
|
||||
console.log(1212, state.data[key])
|
||||
return state.data[key]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -105,7 +105,7 @@ export const crudOptions = (vm) => {
|
|||
getData: (url, dict) => { // 配置此参数会覆盖全局的getRemoteDictFunc
|
||||
return request({ url: url, params: { limit: 999, status: 1 } }).then(ret => {
|
||||
const data = XEUtils.toArrayTree(ret.data.data, { parentKey: 'parent', strict: true })
|
||||
return [{ id: '0', name: '根节点', children: data }]
|
||||
return [{ id: null, name: '根节点', children: data }]
|
||||
})
|
||||
}
|
||||
},
|
||||
|
|
|
@ -1,11 +1,3 @@
|
|||
/*
|
||||
* @创建文件时间: 2021-06-01 22:41:21
|
||||
* @Auther: 猿小天
|
||||
* @最后修改人: 猿小天
|
||||
* @最后修改时间: 2021-08-09 20:21:47
|
||||
* 联系Qq:1638245306
|
||||
* @文件介绍: 字典管理接口
|
||||
*/
|
||||
import { request } from '@/api/service'
|
||||
import XEUtils from 'xe-utils'
|
||||
export const urlPrefix = '/api/system/dictionary/'
|
||||
|
@ -14,7 +6,6 @@ export const urlPrefix = '/api/system/dictionary/'
|
|||
* 列表查询
|
||||
*/
|
||||
export function GetList (query) {
|
||||
query.limit = 999
|
||||
return request({
|
||||
url: urlPrefix,
|
||||
method: 'get',
|
||||
|
|
|
@ -1,8 +1,3 @@
|
|||
import { request } from '@/api/service'
|
||||
import { BUTTON_STATUS_NUMBER } from '@/config/button'
|
||||
import { urlPrefix as dictionaryPrefix } from './api'
|
||||
import XEUtils from 'xe-utils'
|
||||
|
||||
export const crudOptions = (vm) => {
|
||||
return {
|
||||
|
||||
|
@ -22,7 +17,7 @@ export const crudOptions = (vm) => {
|
|||
}
|
||||
},
|
||||
rowHandle: {
|
||||
width: 140,
|
||||
width: 230,
|
||||
view: {
|
||||
thin: true,
|
||||
text: '',
|
||||
|
@ -43,12 +38,18 @@ export const crudOptions = (vm) => {
|
|||
disabled () {
|
||||
return !vm.hasPermissions('Delete')
|
||||
}
|
||||
}
|
||||
},
|
||||
custom: [{
|
||||
text: ' 字典配置',
|
||||
type: 'success',
|
||||
size: 'small',
|
||||
emit: 'dictionaryConfigure'
|
||||
}]
|
||||
},
|
||||
indexRow: { // 或者直接传true,不显示title,不居中
|
||||
title: '序号',
|
||||
align: 'center',
|
||||
width: 100
|
||||
width: 80
|
||||
},
|
||||
viewOptions: {
|
||||
componentType: 'form'
|
||||
|
@ -89,77 +90,8 @@ export const crudOptions = (vm) => {
|
|||
}
|
||||
},
|
||||
{
|
||||
title: '父级字典',
|
||||
key: 'parent',
|
||||
show: false,
|
||||
search: {
|
||||
disabled: true
|
||||
},
|
||||
type: 'cascader',
|
||||
dict: {
|
||||
cache: false,
|
||||
url: dictionaryPrefix,
|
||||
isTree: true,
|
||||
value: 'id', // 数据字典中value字段的属性名
|
||||
label: 'label', // 数据字典中label字段的属性名
|
||||
children: 'children', // 数据字典中children字段的属性名
|
||||
getData: (url, dict) => { // 配置此参数会覆盖全局的getRemoteDictFunc
|
||||
return request({ url: url, params: { limit: 999, status: 1 } }).then(ret => {
|
||||
return [{ id: null, label: '根节点', children: XEUtils.toArrayTree(ret.data.data, { parentKey: 'parent', strict: true }) }]
|
||||
})
|
||||
}
|
||||
|
||||
},
|
||||
form: {
|
||||
component: {
|
||||
props: {
|
||||
elProps: {
|
||||
clearable: true,
|
||||
showAllLevels: false, // 仅显示最后一级
|
||||
props: {
|
||||
checkStrictly: true, // 可以不需要选到最后一级
|
||||
emitPath: false,
|
||||
clearable: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '编码',
|
||||
key: 'code',
|
||||
sortable: true,
|
||||
treeNode: true,
|
||||
search: {
|
||||
disabled: true,
|
||||
component: {
|
||||
props: {
|
||||
clearable: true
|
||||
}
|
||||
}
|
||||
},
|
||||
type: 'input',
|
||||
form: {
|
||||
editDisabled: true,
|
||||
rules: [ // 表单校验规则
|
||||
{ required: true, message: '编码必填项' }
|
||||
],
|
||||
component: {
|
||||
props: {
|
||||
clearable: true
|
||||
},
|
||||
placeholder: '请输入编码'
|
||||
},
|
||||
itemProps: {
|
||||
class: { yxtInput: true }
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '显示值',
|
||||
title: '字典名称',
|
||||
key: 'label',
|
||||
sortable: true,
|
||||
|
||||
search: {
|
||||
disabled: false,
|
||||
|
@ -173,13 +105,13 @@ export const crudOptions = (vm) => {
|
|||
type: 'input',
|
||||
form: {
|
||||
rules: [ // 表单校验规则
|
||||
{ required: true, message: '显示值必填项' }
|
||||
{ required: true, message: '字典名称必填项' }
|
||||
],
|
||||
component: {
|
||||
props: {
|
||||
clearable: true
|
||||
},
|
||||
placeholder: '请输入显示值'
|
||||
placeholder: '请输入字典名称'
|
||||
},
|
||||
itemProps: {
|
||||
class: { yxtInput: true }
|
||||
|
@ -187,9 +119,8 @@ export const crudOptions = (vm) => {
|
|||
}
|
||||
},
|
||||
{
|
||||
title: '实际值',
|
||||
title: '字典编号',
|
||||
key: 'value',
|
||||
sortable: true,
|
||||
|
||||
search: {
|
||||
disabled: true,
|
||||
|
@ -203,13 +134,13 @@ export const crudOptions = (vm) => {
|
|||
type: 'input',
|
||||
form: {
|
||||
rules: [ // 表单校验规则
|
||||
{ required: true, message: '实际值必填项' }
|
||||
{ required: true, message: '字典编号必填项' }
|
||||
],
|
||||
component: {
|
||||
props: {
|
||||
clearable: true
|
||||
},
|
||||
placeholder: '请输入实际值'
|
||||
placeholder: '请输入字典编号'
|
||||
},
|
||||
itemProps: {
|
||||
class: { yxtInput: true }
|
||||
|
@ -220,14 +151,19 @@ export const crudOptions = (vm) => {
|
|||
{
|
||||
title: '状态',
|
||||
key: 'status',
|
||||
sortable: true,
|
||||
width: 90,
|
||||
search: {
|
||||
disabled: false
|
||||
},
|
||||
|
||||
type: 'radio',
|
||||
dict: {
|
||||
data: BUTTON_STATUS_NUMBER
|
||||
data: vm.dictionary('status_bool')
|
||||
},
|
||||
component: {
|
||||
props: {
|
||||
options: []
|
||||
}
|
||||
},
|
||||
form: {
|
||||
value: 1,
|
||||
|
@ -238,8 +174,7 @@ export const crudOptions = (vm) => {
|
|||
{
|
||||
title: '排序',
|
||||
key: 'sort',
|
||||
sortable: true,
|
||||
|
||||
width: 90,
|
||||
type: 'number',
|
||||
form: {
|
||||
value: 1,
|
||||
|
@ -247,6 +182,11 @@ export const crudOptions = (vm) => {
|
|||
}
|
||||
}
|
||||
}
|
||||
].concat(vm.commonEndColumns())
|
||||
].concat(vm.commonEndColumns({
|
||||
description: {
|
||||
showForm: true,
|
||||
showTable: true
|
||||
}
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<template>
|
||||
<d2-container :class="{ 'page-compact': crud.pageOptions.compact }">
|
||||
<!-- <template slot="header">测试页面1</template>-->
|
||||
<d2-crud-x ref="d2Crud" v-bind="_crudProps" v-on="_crudListeners">
|
||||
<d2-crud-x ref="d2Crud" v-bind="_crudProps" v-on="_crudListeners" @dictionaryConfigure="dictionaryConfigure">
|
||||
<div slot="header">
|
||||
<crud-search
|
||||
ref="search"
|
||||
|
@ -30,6 +30,12 @@
|
|||
/>
|
||||
</div>
|
||||
</d2-crud-x>
|
||||
<el-drawer
|
||||
title="字典列表"
|
||||
:visible.sync="drawer"
|
||||
:size="700">
|
||||
<sub-dictionary style="margin-top: 80px;margin-left: 10px" :dictionaryRow="dictionaryRow"></sub-dictionary>
|
||||
</el-drawer>
|
||||
</d2-container>
|
||||
</template>
|
||||
|
||||
|
@ -37,17 +43,23 @@
|
|||
import * as api from './api'
|
||||
import { crudOptions } from './crud'
|
||||
import { d2CrudPlus } from 'd2-crud-plus'
|
||||
import SubDictionary from '@/views/system/dictionary/subDictionary/index'
|
||||
export default {
|
||||
name: 'dictionary',
|
||||
components: { SubDictionary },
|
||||
mixins: [d2CrudPlus.crud],
|
||||
data () {
|
||||
return {}
|
||||
return {
|
||||
drawer: false,
|
||||
dictionaryRow: {}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getCrudOptions () {
|
||||
return crudOptions(this)
|
||||
},
|
||||
pageRequest (query) {
|
||||
query.is_value = false
|
||||
return api.GetList(query)
|
||||
},
|
||||
addRequest (row) {
|
||||
|
@ -61,13 +73,10 @@ export default {
|
|||
delRequest (row) {
|
||||
return api.DelObj(row.id)
|
||||
},
|
||||
// 授权
|
||||
createPermission (scope) {
|
||||
this.$router.push({
|
||||
name: 'menuButton',
|
||||
params: { id: scope.row.id },
|
||||
query: { name: scope.row.name }
|
||||
})
|
||||
// 字典配置
|
||||
dictionaryConfigure (scope) {
|
||||
this.drawer = true
|
||||
this.dictionaryRow = scope.row
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
import { request } from '@/api/service'
|
||||
import XEUtils from 'xe-utils'
|
||||
export const urlPrefix = '/api/system/dictionary/'
|
||||
|
||||
/**
|
||||
* 列表查询
|
||||
*/
|
||||
export function GetList (query) {
|
||||
return request({
|
||||
url: urlPrefix,
|
||||
method: 'get',
|
||||
params: query
|
||||
}).then(res => {
|
||||
// 将列表数据转换为树形数据
|
||||
res.data.data = XEUtils.toArrayTree(res.data.data, { parentKey: 'parent' })
|
||||
return res
|
||||
})
|
||||
}
|
||||
/**
|
||||
* 新增
|
||||
*/
|
||||
export function createObj (obj) {
|
||||
return request({
|
||||
url: urlPrefix,
|
||||
method: 'post',
|
||||
data: obj
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改
|
||||
*/
|
||||
export function UpdateObj (obj) {
|
||||
return request({
|
||||
url: urlPrefix + obj.id + '/',
|
||||
method: 'put',
|
||||
data: obj
|
||||
})
|
||||
}
|
||||
/**
|
||||
* 删除
|
||||
*/
|
||||
export function DelObj (id) {
|
||||
return request({
|
||||
url: urlPrefix + id + '/',
|
||||
method: 'delete',
|
||||
data: { id }
|
||||
})
|
||||
}
|
|
@ -0,0 +1,272 @@
|
|||
import { BUTTON_STATUS_BOOL } from '@/config/button'
|
||||
|
||||
export const crudOptions = (vm) => {
|
||||
return {
|
||||
|
||||
pageOptions: {
|
||||
compact: true
|
||||
},
|
||||
options: {
|
||||
rowId: 'id',
|
||||
height: '100%', // 表格高度100%, 使用toolbar必须设置
|
||||
border: false
|
||||
},
|
||||
rowHandle: {
|
||||
width: 140,
|
||||
view: {
|
||||
thin: true,
|
||||
text: '',
|
||||
disabled () {
|
||||
return !vm.hasPermissions('Retrieve')
|
||||
}
|
||||
},
|
||||
edit: {
|
||||
thin: true,
|
||||
text: '',
|
||||
disabled () {
|
||||
return !vm.hasPermissions('Update')
|
||||
}
|
||||
},
|
||||
remove: {
|
||||
thin: true,
|
||||
text: '',
|
||||
disabled () {
|
||||
return !vm.hasPermissions('Delete')
|
||||
}
|
||||
}
|
||||
},
|
||||
viewOptions: {
|
||||
componentType: 'form'
|
||||
},
|
||||
formOptions: {
|
||||
appendToBody: true, // 子表格必须 否则弹出对话框无法显示最顶层
|
||||
defaultSpan: 24, // 默认的表单 span
|
||||
width: '35%'
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
title: '名称',
|
||||
key: 'label',
|
||||
|
||||
search: {
|
||||
disabled: false,
|
||||
component: {
|
||||
props: {
|
||||
clearable: true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
type: 'input',
|
||||
form: {
|
||||
rules: [ // 表单校验规则
|
||||
{ required: true, message: '名称必填项' }
|
||||
],
|
||||
component: {
|
||||
props: {
|
||||
clearable: true
|
||||
},
|
||||
placeholder: '请输入名称'
|
||||
},
|
||||
itemProps: {
|
||||
class: { yxtInput: true }
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '数据值类型',
|
||||
type: 'select',
|
||||
key: 'type',
|
||||
search: {
|
||||
disabled: true,
|
||||
component: {
|
||||
props: {
|
||||
clearable: true
|
||||
}
|
||||
}
|
||||
},
|
||||
show: false,
|
||||
dict: {
|
||||
data: [
|
||||
{ label: 'text', value: 0 },
|
||||
{ label: 'number', value: 1 },
|
||||
{ label: 'date', value: 2 },
|
||||
{ label: 'datetime', value: 3 },
|
||||
{ label: 'time', value: 4 },
|
||||
{ label: 'file', value: 5 },
|
||||
{ label: 'boolean', value: 6 },
|
||||
{ label: 'images', value: 7 }
|
||||
]
|
||||
},
|
||||
form: {
|
||||
rules: [ // 表单校验规则
|
||||
{ required: true, message: '数据值类型必填项' }
|
||||
],
|
||||
value: 0,
|
||||
component: {
|
||||
props: {
|
||||
clearable: true
|
||||
},
|
||||
placeholder: '请选择数据值类型'
|
||||
},
|
||||
itemProps: {
|
||||
class: { yxtInput: true }
|
||||
},
|
||||
valueChange (key, value, form, { getColumn, mode, component, immediate, getComponent }) {
|
||||
const template = vm.getEditFormTemplate('value')
|
||||
// 选择框重新选择后,情况value值
|
||||
if (!immediate) {
|
||||
form.value = undefined
|
||||
}
|
||||
if (value === 0) {
|
||||
template.component.name = 'el-input'
|
||||
} else if (value === 1) {
|
||||
template.component.name = 'el-input-number'
|
||||
} else if (value === 2) {
|
||||
template.component.name = 'el-date-picker'
|
||||
template.component.props = {
|
||||
type: 'date',
|
||||
valueFormat: 'yyyy-MM-dd'
|
||||
}
|
||||
} else if (value === 3) {
|
||||
template.component.name = 'el-date-picker'
|
||||
template.component.props = {
|
||||
type: 'datetime',
|
||||
valueFormat: 'yyyy-MM-dd HH:mm:ss'
|
||||
}
|
||||
} else if (value === 4) {
|
||||
template.component.name = 'el-time-picker'
|
||||
template.component.props = {
|
||||
pickerOptions: {
|
||||
arrowControl: true
|
||||
},
|
||||
valueFormat: 'HH:mm:ss'
|
||||
}
|
||||
} else if (value === 5) {
|
||||
template.component.name = 'd2p-file-uploader'
|
||||
template.component.props = { elProps: { listType: 'text' } }
|
||||
} else if (value === 6) {
|
||||
template.component.name = 'dict-switch'
|
||||
template.component.value = true
|
||||
template.component.props = {
|
||||
dict: {
|
||||
data: [
|
||||
{ label: '是', value: 'true' },
|
||||
{ label: '否', value: 'false' }
|
||||
]
|
||||
}
|
||||
}
|
||||
} else if (value === 7) {
|
||||
template.component.name = 'd2p-cropper-uploader'
|
||||
template.component.props = { accept: '.png,.jpeg,.jpg,.ico,.bmp,.gif', cropper: { viewMode: 1 } }
|
||||
}
|
||||
},
|
||||
valueChangeImmediate: true
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '数据值',
|
||||
key: 'value',
|
||||
search: {
|
||||
disabled: true,
|
||||
component: {
|
||||
props: {
|
||||
clearable: true
|
||||
}
|
||||
}
|
||||
},
|
||||
view: {
|
||||
component: { props: { height: 100, width: 100 } }
|
||||
},
|
||||
// 提交时,处理数据
|
||||
valueResolve (row, col) {
|
||||
const value = row[col.key]
|
||||
const type = row.type
|
||||
if (type === 5 || type === 7) {
|
||||
if (value != null) {
|
||||
if (value.length >= 0) {
|
||||
if (value instanceof Array) {
|
||||
row[col.key] = value.toString()
|
||||
} else {
|
||||
row[col.key] = value
|
||||
}
|
||||
} else {
|
||||
row[col.key] = null
|
||||
}
|
||||
}
|
||||
} else {
|
||||
row[col.key] = value
|
||||
}
|
||||
},
|
||||
// 接收时,处理数据
|
||||
valueBuilder (row, col) {
|
||||
const value = row[col.key]
|
||||
const type = row.type
|
||||
if (type === 5 || type === 7) {
|
||||
if (value != null && value) {
|
||||
row[col.key] = value.split(',')
|
||||
}
|
||||
} else {
|
||||
row[col.key] = value
|
||||
}
|
||||
},
|
||||
type: 'input',
|
||||
form: {
|
||||
rules: [ // 表单校验规则
|
||||
{ required: true, message: '数据值必填项' }
|
||||
],
|
||||
component: {
|
||||
props: {
|
||||
clearable: true
|
||||
},
|
||||
placeholder: '请输入数据值'
|
||||
},
|
||||
itemProps: {
|
||||
class: { yxtInput: true }
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
title: '状态',
|
||||
key: 'status',
|
||||
width: 80,
|
||||
search: {
|
||||
disabled: false
|
||||
},
|
||||
type: 'radio',
|
||||
dict: {
|
||||
data: BUTTON_STATUS_BOOL
|
||||
},
|
||||
form: {
|
||||
value: true,
|
||||
rules: [ // 表单校验规则
|
||||
{ required: true, message: '状态必填项' }
|
||||
],
|
||||
component: {
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '排序',
|
||||
key: 'sort',
|
||||
width: 70,
|
||||
type: 'number',
|
||||
form: {
|
||||
value: 1,
|
||||
component: {
|
||||
}
|
||||
}
|
||||
}
|
||||
].concat(vm.commonEndColumns({
|
||||
update_datetime: {
|
||||
showForm: false,
|
||||
showTable: false
|
||||
},
|
||||
create_datetime: {
|
||||
showForm: false,
|
||||
showTable: false
|
||||
}
|
||||
}))
|
||||
}
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
<template>
|
||||
<d2-container>
|
||||
<d2-crud-x ref="d2Crud" v-bind="_crudProps" v-on="_crudListeners" @dictionaryConfigure="dictionaryConfigure">
|
||||
<div slot="header">
|
||||
<crud-search
|
||||
ref="search"
|
||||
:options="crud.searchOptions"
|
||||
@submit="handleSearch"
|
||||
/>
|
||||
<el-button-group>
|
||||
<el-button size="small" type="primary" @click="addRow"
|
||||
><i class="el-icon-plus" /> 新增</el-button
|
||||
>
|
||||
</el-button-group>
|
||||
<crud-toolbar
|
||||
:search.sync="crud.searchOptions.show"
|
||||
:compact.sync="crud.pageOptions.compact"
|
||||
:columns="crud.columns"
|
||||
@refresh="doRefresh()"
|
||||
@columns-filter-changed="handleColumnsFilterChanged"
|
||||
/>
|
||||
</div>
|
||||
</d2-crud-x>
|
||||
<el-drawer
|
||||
title="我是标题"
|
||||
:visible.sync="drawer"
|
||||
size="40%">
|
||||
<span>我来啦!</span>
|
||||
</el-drawer>
|
||||
</d2-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as api from './api'
|
||||
import { crudOptions } from './crud'
|
||||
import { d2CrudPlus } from 'd2-crud-plus'
|
||||
export default {
|
||||
name: 'subDictionary',
|
||||
mixins: [d2CrudPlus.crud],
|
||||
props: {
|
||||
// 容器样式
|
||||
dictionaryRow: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
drawer: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getCrudOptions () {
|
||||
return crudOptions(this)
|
||||
},
|
||||
pageRequest (query) {
|
||||
query.is_value = true
|
||||
query.parent = this.dictionaryRow.id
|
||||
return api.GetList(query)
|
||||
},
|
||||
addRequest (row) {
|
||||
d2CrudPlus.util.dict.clear()
|
||||
row.is_value = true
|
||||
row.parent = this.dictionaryRow.id
|
||||
return api.createObj(row)
|
||||
},
|
||||
updateRequest (row) {
|
||||
d2CrudPlus.util.dict.clear()
|
||||
row.is_value = true
|
||||
row.parent = this.dictionaryRow.id
|
||||
return api.UpdateObj(row)
|
||||
},
|
||||
delRequest (row) {
|
||||
return api.DelObj(row.id)
|
||||
},
|
||||
// 字典配置
|
||||
dictionaryConfigure (scope) {
|
||||
this.drawer = true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.yxtInput {
|
||||
.el-form-item__label {
|
||||
color: #49a1ff;
|
||||
}
|
||||
}
|
||||
</style>
|
Loading…
Reference in New Issue