新增:字典管理功能

pull/56/head
李强 2022-05-10 15:09:40 +08:00
parent 0118b8dca2
commit 8faeed2ff7
14 changed files with 649 additions and 141 deletions

View File

@ -30,6 +30,7 @@ from dvadmin.system.views.login import (
ApiLogin, ApiLogin,
LogoutView, LogoutView,
) )
from dvadmin.system.views.system_config import InitSettingsViewSet
from dvadmin.utils.swagger import CustomOpenAPISchemaGenerator from dvadmin.utils.swagger import CustomOpenAPISchemaGenerator
schema_view = get_schema_view( schema_view = get_schema_view(
@ -72,6 +73,7 @@ urlpatterns = (
), ),
path("api/captcha/", CaptchaView.as_view()), path("api/captcha/", CaptchaView.as_view()),
path("api/captcha/status/", CaptchaStatusView.as_view()), path("api/captcha/status/", CaptchaStatusView.as_view()),
path("api/init/settings/", InitSettingsViewSet.as_view()),
path("apiLogin/", ApiLogin.as_view()), path("apiLogin/", ApiLogin.as_view()),
] ]
+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

View File

@ -34,7 +34,7 @@ TABLE_PREFIX = "sys_"
# ================================================= # # ================================================= #
# ****************** 功能 启停 ******************* # # ****************** 功能 启停 ******************* #
# ================================================= # # ================================================= #
DEBUG = False DEBUG = True
# 启动登录详细概略获取(通过调用api获取ip详细地址。如果是内网关闭即可) # 启动登录详细概略获取(通过调用api获取ip详细地址。如果是内网关闭即可)
ENABLE_LOGIN_ANALYSIS_LOG = True ENABLE_LOGIN_ANALYSIS_LOG = True
# 是否启用登录验证码不需要可以设置为False线上环境建议开启 # 是否启用登录验证码不需要可以设置为False线上环境建议开启

View File

@ -166,13 +166,23 @@ class MenuButton(CoreModel):
class Dictionary(CoreModel): class Dictionary(CoreModel):
code = models.CharField(max_length=100, blank=True, null=True, verbose_name="编码", help_text="编码") TYPE_LIST = (
label = models.CharField(max_length=100, blank=True, null=True, verbose_name="显示名称", help_text="显示名称") (0, 'text'),
value = models.CharField(max_length=100, blank=True, null=True, verbose_name="实际值", help_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, parent = models.ForeignKey(to='self', related_name='sublist', db_constraint=False, on_delete=models.PROTECT,
blank=True, null=True, blank=True, null=True, verbose_name="父级", help_text="父级")
verbose_name="父级", help_text="父级") type = models.IntegerField(choices=TYPE_LIST, default=0, verbose_name="数据值类型", help_text="数据值类型")
status = models.BooleanField(default=True, blank=True, 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="显示排序") 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="备注") remark = models.CharField(max_length=2000, blank=True, null=True, verbose_name="备注", help_text="备注")

View File

@ -6,12 +6,11 @@
@Created on: 2021/6/3 003 0:30 @Created on: 2021/6/3 003 0:30
@Remark: 字典管理 @Remark: 字典管理
""" """
from rest_framework import serializers
from dvadmin.system.models import Dictionary from dvadmin.system.models import Dictionary
from dvadmin.utils.json_response import SuccessResponse from dvadmin.utils.json_response import SuccessResponse
from dvadmin.utils.serializers import CustomModelSerializer from dvadmin.utils.serializers import CustomModelSerializer
from dvadmin.utils.viewset import CustomModelViewSet from dvadmin.utils.viewset import CustomModelViewSet
from rest_framework import serializers
class DictionarySerializer(CustomModelSerializer): class DictionarySerializer(CustomModelSerializer):
@ -42,16 +41,15 @@ class DictionaryTreeSerializer(CustomModelSerializer):
children = serializers.SerializerMethodField(read_only=True) children = serializers.SerializerMethodField(read_only=True)
def get_children(self, instance): 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: if queryset:
serializer = DictionaryTreeSerializer(queryset, many=True) return queryset
return serializer.data
else: else:
return None return []
class Meta: class Meta:
model = Dictionary model = Dictionary
fields = "__all__" fields = ['id', 'value', 'children']
read_only_fields = ["id"] read_only_fields = ["id"]
@ -68,3 +66,15 @@ class DictionaryViewSet(CustomModelViewSet):
serializer_class = DictionarySerializer serializer_class = DictionarySerializer
extra_filter_backends = [] extra_filter_backends = []
search_fields = ['label'] 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)

View File

@ -10,9 +10,9 @@ import django_filters
from django.db.models import Q from django.db.models import Q
from django_filters.rest_framework import BooleanFilter from django_filters.rest_framework import BooleanFilter
from rest_framework import serializers from rest_framework import serializers
from rest_framework.views import APIView
from dvadmin.system.models import SystemConfig from dvadmin.system.models import SystemConfig
from dvadmin.utils.filters import DataLevelPermissionsFilter
from dvadmin.utils.json_response import DetailResponse, SuccessResponse, ErrorResponse from dvadmin.utils.json_response import DetailResponse, SuccessResponse, ErrorResponse
from dvadmin.utils.models import get_all_models_objects from dvadmin.utils.models import get_all_models_objects
from dvadmin.utils.serializers import CustomModelSerializer from dvadmin.utils.serializers import CustomModelSerializer
@ -31,17 +31,17 @@ class SystemConfigCreateSerializer(CustomModelSerializer):
fields = "__all__" fields = "__all__"
read_only_fields = ["id"] read_only_fields = ["id"]
def validate_key(self, value): def validate_key(self, value):
""" """
验证key是否允许重复 验证key是否允许重复
parent为空时不允许重复,反之允许 parent为空时不允许重复,反之允许
""" """
instance = SystemConfig.objects.filter(key=value,parent__isnull=True).exists() instance = SystemConfig.objects.filter(key=value, parent__isnull=True).exists()
if instance: if instance:
raise CustomValidationError('已存在相同变量名') raise CustomValidationError('已存在相同变量名')
return value return value
class SystemConfigSerializer(CustomModelSerializer): class SystemConfigSerializer(CustomModelSerializer):
""" """
系统配置-序列化器 系统配置-序列化器
@ -112,17 +112,9 @@ class SystemConfigFilter(django_filters.rest_framework.FilterSet):
fields = ['id', 'parent', 'status', 'parent__isnull'] fields = ['id', 'parent', 'status', 'parent__isnull']
class SystemConfigViewSet(CustomModelViewSet): class SystemConfigViewSet(CustomModelViewSet):
""" """
系统配置接口 系统配置接口
list:查询
create:新增
update:修改
retrieve:详情
destroy:删除
""" """
queryset = SystemConfig.objects.order_by('sort', 'create_datetime') queryset = SystemConfig.objects.order_by('sort', 'create_datetime')
serializer_class = SystemConfigChinldernSerializer serializer_class = SystemConfigChinldernSerializer
@ -152,7 +144,7 @@ class SystemConfigViewSet(CustomModelViewSet):
res = [ele.get('table') for ele in get_all_models_objects().values()] res = [ele.get('table') for ele in get_all_models_objects().values()]
return DetailResponse(msg="获取成功", data=res) 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 setting = instance.setting
if setting is None: if setting is None:
return ErrorResponse(msg="查询出错了~") return ErrorResponse(msg="查询出错了~")
table = setting.get('table') #获取model名 table = setting.get('table') # 获取model名
model = get_all_models_objects(table).get("object", {}) model = get_all_models_objects(table).get("object", {})
# 自己判断一下不存在 # 自己判断一下不存在
queryset = model.objects.values() queryset = model.objects.values()
@ -181,15 +173,14 @@ class SystemConfigViewSet(CustomModelViewSet):
return self.get_paginated_response(queryset) return self.get_paginated_response(queryset)
return SuccessResponse(msg="获取成功", data=queryset, total=len(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 body = request.query_params
var_name = body.get('varName',None) var_name = body.get('varName', None)
table = body.get('table',None) table = body.get('table', None)
instance = SystemConfig.objects.filter(key=var_name,setting__table=table).first() instance = SystemConfig.objects.filter(key=var_name, setting__table=table).first()
if instance is None: if instance is None:
return ErrorResponse(msg="未获取到关联信息") return ErrorResponse(msg="未获取到关联信息")
relation_id = body.get('relationIds', None) relation_id = body.get('relationIds', None)
@ -204,4 +195,23 @@ class SystemConfigViewSet(CustomModelViewSet):
if queryset is None: if queryset is None:
return ErrorResponse(msg="未获取到关联信息") return ErrorResponse(msg="未获取到关联信息")
serializer = SystemConfigChinldernSerializer(queryset.parent) 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)

View File

@ -69,3 +69,52 @@
*::-webkit-scrollbar-thumb:hover { *::-webkit-scrollbar-thumb:hover {
background-color: #bbb; 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; */
}

View File

@ -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]
}
}
}

View File

@ -105,7 +105,7 @@ export const crudOptions = (vm) => {
getData: (url, dict) => { // 配置此参数会覆盖全局的getRemoteDictFunc getData: (url, dict) => { // 配置此参数会覆盖全局的getRemoteDictFunc
return request({ url: url, params: { limit: 999, status: 1 } }).then(ret => { return request({ url: url, params: { limit: 999, status: 1 } }).then(ret => {
const data = XEUtils.toArrayTree(ret.data.data, { parentKey: 'parent', strict: true }) const data = XEUtils.toArrayTree(ret.data.data, { parentKey: 'parent', strict: true })
return [{ id: '0', name: '根节点', children: data }] return [{ id: null, name: '根节点', children: data }]
}) })
} }
}, },

View File

@ -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 { request } from '@/api/service'
import XEUtils from 'xe-utils' import XEUtils from 'xe-utils'
export const urlPrefix = '/api/system/dictionary/' export const urlPrefix = '/api/system/dictionary/'
@ -14,7 +6,6 @@ export const urlPrefix = '/api/system/dictionary/'
* 列表查询 * 列表查询
*/ */
export function GetList (query) { export function GetList (query) {
query.limit = 999
return request({ return request({
url: urlPrefix, url: urlPrefix,
method: 'get', method: 'get',

View File

@ -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) => { export const crudOptions = (vm) => {
return { return {
@ -22,7 +17,7 @@ export const crudOptions = (vm) => {
} }
}, },
rowHandle: { rowHandle: {
width: 140, width: 230,
view: { view: {
thin: true, thin: true,
text: '', text: '',
@ -43,12 +38,18 @@ export const crudOptions = (vm) => {
disabled () { disabled () {
return !vm.hasPermissions('Delete') return !vm.hasPermissions('Delete')
} }
} },
custom: [{
text: ' 字典配置',
type: 'success',
size: 'small',
emit: 'dictionaryConfigure'
}]
}, },
indexRow: { // 或者直接传true,不显示title不居中 indexRow: { // 或者直接传true,不显示title不居中
title: '序号', title: '序号',
align: 'center', align: 'center',
width: 100 width: 80
}, },
viewOptions: { viewOptions: {
componentType: 'form' componentType: 'form'
@ -89,77 +90,8 @@ export const crudOptions = (vm) => {
} }
}, },
{ {
title: '父级字典', 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: '显示值',
key: 'label', key: 'label',
sortable: true,
search: { search: {
disabled: false, disabled: false,
@ -173,13 +105,13 @@ export const crudOptions = (vm) => {
type: 'input', type: 'input',
form: { form: {
rules: [ // 表单校验规则 rules: [ // 表单校验规则
{ required: true, message: '显示值必填项' } { required: true, message: '字典名称必填项' }
], ],
component: { component: {
props: { props: {
clearable: true clearable: true
}, },
placeholder: '请输入显示值' placeholder: '请输入字典名称'
}, },
itemProps: { itemProps: {
class: { yxtInput: true } class: { yxtInput: true }
@ -187,9 +119,8 @@ export const crudOptions = (vm) => {
} }
}, },
{ {
title: '实际值', title: '字典编号',
key: 'value', key: 'value',
sortable: true,
search: { search: {
disabled: true, disabled: true,
@ -203,13 +134,13 @@ export const crudOptions = (vm) => {
type: 'input', type: 'input',
form: { form: {
rules: [ // 表单校验规则 rules: [ // 表单校验规则
{ required: true, message: '实际值必填项' } { required: true, message: '字典编号必填项' }
], ],
component: { component: {
props: { props: {
clearable: true clearable: true
}, },
placeholder: '请输入实际值' placeholder: '请输入字典编号'
}, },
itemProps: { itemProps: {
class: { yxtInput: true } class: { yxtInput: true }
@ -220,14 +151,19 @@ export const crudOptions = (vm) => {
{ {
title: '状态', title: '状态',
key: 'status', key: 'status',
sortable: true, width: 90,
search: { search: {
disabled: false disabled: false
}, },
type: 'radio', type: 'radio',
dict: { dict: {
data: BUTTON_STATUS_NUMBER data: vm.dictionary('status_bool')
},
component: {
props: {
options: []
}
}, },
form: { form: {
value: 1, value: 1,
@ -238,8 +174,7 @@ export const crudOptions = (vm) => {
{ {
title: '排序', title: '排序',
key: 'sort', key: 'sort',
sortable: true, width: 90,
type: 'number', type: 'number',
form: { form: {
value: 1, value: 1,
@ -247,6 +182,11 @@ export const crudOptions = (vm) => {
} }
} }
} }
].concat(vm.commonEndColumns()) ].concat(vm.commonEndColumns({
description: {
showForm: true,
showTable: true
}
}))
} }
} }

View File

@ -9,7 +9,7 @@
<template> <template>
<d2-container :class="{ 'page-compact': crud.pageOptions.compact }"> <d2-container :class="{ 'page-compact': crud.pageOptions.compact }">
<!-- <template slot="header">测试页面1</template>--> <!-- <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"> <div slot="header">
<crud-search <crud-search
ref="search" ref="search"
@ -30,6 +30,12 @@
/> />
</div> </div>
</d2-crud-x> </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> </d2-container>
</template> </template>
@ -37,17 +43,23 @@
import * as api from './api' import * as api from './api'
import { crudOptions } from './crud' import { crudOptions } from './crud'
import { d2CrudPlus } from 'd2-crud-plus' import { d2CrudPlus } from 'd2-crud-plus'
import SubDictionary from '@/views/system/dictionary/subDictionary/index'
export default { export default {
name: 'dictionary', name: 'dictionary',
components: { SubDictionary },
mixins: [d2CrudPlus.crud], mixins: [d2CrudPlus.crud],
data () { data () {
return {} return {
drawer: false,
dictionaryRow: {}
}
}, },
methods: { methods: {
getCrudOptions () { getCrudOptions () {
return crudOptions(this) return crudOptions(this)
}, },
pageRequest (query) { pageRequest (query) {
query.is_value = false
return api.GetList(query) return api.GetList(query)
}, },
addRequest (row) { addRequest (row) {
@ -61,13 +73,10 @@ export default {
delRequest (row) { delRequest (row) {
return api.DelObj(row.id) return api.DelObj(row.id)
}, },
// //
createPermission (scope) { dictionaryConfigure (scope) {
this.$router.push({ this.drawer = true
name: 'menuButton', this.dictionaryRow = scope.row
params: { id: scope.row.id },
query: { name: scope.row.name }
})
} }
} }
} }

View File

@ -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 }
})
}

View File

@ -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
}
}))
}
}

View File

@ -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>