Java实现自定义字段(不修改表结构)

目录

前言

效果图

一、后端java层

1.枚举类

2.服务实现类

1.自定义字段管理

2.自定义字段value值管理

二、数据访问层

1.表结构

2.sql语句

三、前端展示层

1.配置自定义字段

2.展示自定义字段(编辑则展示字段和value值)

3.添加自定义字段value值

总结


前言

在某些场景下用户需要自己配置字段并添加数据的时候,我们可以做一个根据不同模块实现字段自定义配置的功能以供不同系统的需求。

效果图

Java实现自定义字段(不修改表结构)_第1张图片

图一

Java实现自定义字段(不修改表结构)_第2张图片

图二

Java实现自定义字段(不修改表结构)_第3张图片

图三

一、后端java层

1.枚举类

因为模块的类型是自己定义的,所以需要加一个类型枚举类,我这里是oa系统的模块,你们可以根据自己系统进行定义。

代码如下:

/**
 * 

* 自定义字段类型枚举类 *

* * @author 刘易彦 * @custom.date 2024/9/20 14:46 */ public class CustomTypeConstants { /** *

* 私有化构造方法 *

* * @author 刘易彦 * @custom.date 2024/6/2 14:46 */ private CustomTypeConstants() { } /** * 角色管理 */ public static final String ROLE = "role"; /** * 岗位信息 */ public static final String POST = "post"; /** * 用人需求 */ public static final String EMPLOYMENT = "employment"; /** * 招聘面试 */ public static final String INTERVIEW = "interview"; /** * 人才资源池 */ public static final String HUMAN_RESOURCES = "human_resources"; /** * 本省同行公司 */ public static final String SAME_PEER = "same_peer"; /** * 外省同行公司 */ public static final String NOT_SAME_PEER = "not_same_peer"; /** * 汽车行业公司 */ public static final String CAR_PEER = "car_peer"; /** * 入职申请 */ public static final String ENTRY = "entry"; /** * 转正申请 */ public static final String REGULAR = "regular"; /** * 员工档案 */ public static final String ARCHIVES = "archives"; /** * 合同管理 */ public static final String CONTRACT = "contract"; /** * 培训需求 */ public static final String TRAIN_NEEDS = "trainNeeds"; /** * 社保 */ public static final String SOCIAL_SECURITY = "socialSecurity"; /** * 培训执行 */ public static final String TRAIN_SCHEDULE = "trainSchedule"; /** * 其他培训考试 */ public static final String TRAIN_OTHER_TEST = "trainOtherTest";

2.服务实现类

实现分为两层进行展示,第一层为自定义字段的管理,第二层为模块内对自定义字段管理value值。

1.自定义字段管理

对应效果图中的图一。

代码如下:

 @Override
    public LayUiAdminResultVo addCustomField(CustomFields customFields) {
        customFields.setPossibleValues(customFields.getPossibleValues().replaceAll(",",","));
        int insert = this.customFieldsMapper.insert(customFields);
        if (insert == 1) {
            return LayUiAdminResultVo.ok(WebResponseConstants.SUCCESS);
        }
        return LayUiAdminResultVo.ok(WebResponseConstants.FAIL);
    }

    @Override
    public LayUiAdminResultVo editCustomField(CustomFields customFields) {
        customFields.setPossibleValues(customFields.getPossibleValues().replaceAll(",",","));
        int update = this.customFieldsMapper.updateById(customFields);
        if (update == 1) {
            return LayUiAdminResultVo.ok(WebResponseConstants.SUCCESS);
        }
        return LayUiAdminResultVo.ok(WebResponseConstants.FAIL);
    }

    @Override
    public LayUiAdminResultVo delCustomField(String id,String type) {
        LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(CustomValues::getCustomFieldId, id);
        lambdaQueryWrapper.eq(CustomValues::getCustomizedType, type);
        int delete = this.customValuesMapper.delete(lambdaQueryWrapper);
        int delete1 = customFieldsMapper.deleteById(id);
        if (delete1 == 1) {
            return LayUiAdminResultVo.ok(WebResponseConstants.SUCCESS);
        }
        return LayUiAdminResultVo.ok(WebResponseConstants.FAIL);
    }

    @Override
    public IPage getCustomFieldList(int current, int size, String keyWords) {
        LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>();
        IPage ipage = new Page<>(current, size);
        if (StringUtils.isNotBlank(keyWords)) {
            lambdaQueryWrapper.like(CustomFields::getName, keyWords);
        }
        lambdaQueryWrapper.orderByAsc(CustomFields::getType);
        return this.customFieldsMapper.selectPage(ipage, lambdaQueryWrapper);
    }

2.自定义字段value值管理

对应效果图中的图二。

代码如下:

@Override
    public LayUiAdminResultVo addCustomValue(JSONObject jsonObject) {
        JSONObject jsonObject1 = jsonObject.getJSONObject("value");
        for (String key :  jsonObject1.keySet()) {
            String value = jsonObject1.get(key).toString();
            LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(CustomValues::getCustomizedType, jsonObject.getString("customizedType"));
            lambdaQueryWrapper.eq(CustomValues::getCustomizedId,jsonObject.getLong("customizedId"));
            lambdaQueryWrapper.eq(CustomValues::getCustomFieldId,key);
            CustomValues customValues = customValuesMapper.selectOne(lambdaQueryWrapper);
            if(customValues!=null){
                customValues.setValue(value);
                int update = customValuesMapper.updateById(customValues);
            }else{
                CustomValues customValues2 = new CustomValues();
                customValues2.setCustomFieldId(Long.parseLong(key));
                customValues2.setValue(value);
                customValues2.setCustomizedType(jsonObject.getString("customizedType"));
                customValues2.setCustomizedId(jsonObject.getLong("customizedId"));
                int insert = customValuesMapper.insert(customValues2);
            }
        }
        return LayUiAdminResultVo.ok(WebResponseConstants.SUCCESS);
    }

    @Override
    public LayUiAdminResultVo delCustomValue(String id,String type) {
        LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(CustomValues::getCustomizedId, id);
        lambdaQueryWrapper.eq(CustomValues::getCustomizedType, type);
        int delete = this.customValuesMapper.delete(lambdaQueryWrapper);
        if (delete > 0) {
            return LayUiAdminResultVo.ok(WebResponseConstants.SUCCESS);
        }
        return LayUiAdminResultVo.ok(WebResponseConstants.FAIL);
    }

二、数据访问层

1.表结构

自定义字段表:

Java实现自定义字段(不修改表结构)_第4张图片自定义字段value表

Java实现自定义字段(不修改表结构)_第5张图片

2.sql语句

根据模块类型和业务id联表查询自定义字段和对应的value值。

代码如下:

 

三、前端展示层

1.配置自定义字段

这里以添加为例,编辑雷同就不展示了(我这里的js代码都是以layui为例的,不同框架写法可能有所不同,请注意)。

html页面代码如下:

配置信息

 js代码如下:

 // 监听select选择
        form.on('select(fieldFormat)', function(data){
            let value = data.value;
            common.verifyDefaultValue('defaultDiv','defaultValue','possibleValues',value);
        });

        // 监听select选择
        form.on('select(type)', function(data){
            let selectedText = data.elem[data.elem.selectedIndex].text; // 获取选中的文本值
            $("#typeName").val(selectedText);
        });

 verifyDefaultValue: function (defaultDiv, defaultValue,possibleValues,value) {
            if(value==='list'){
                $("#"+possibleValues).attr("disabled", false);
                $("#"+possibleValues).attr("lay-verify", 'required');
            }else {
                $("#"+possibleValues).attr("disabled", true);
                $("#"+possibleValues).attr("lay-verify", '');
            }
            if(value !== 'date'){
                $("#"+defaultDiv).empty();
                $("#"+defaultDiv).append('');
            }
            if(value==='int'){
                $("#"+defaultValue).attr('lay-verify', 'number');
                $("#"+defaultValue).attr('placeholder', '请输入默认值(数字)');
            }else if(value==='date'){
                $("#"+defaultValue).attr('lay-verify', '');
                $("#"+defaultValue).attr('placeholder', '请输入默认值(日期)');
                laydate.render({
                    elem: '#'+defaultValue
                    , type: 'date'
                });
            }else if(value==='phone'){
                $("#"+defaultValue).attr('lay-verify', 'phone');
                $("#"+defaultValue).attr('placeholder', '请输入默认值(手机号)');
            }else if(value==='email'){
                $("#"+defaultValue).attr('lay-verify', 'email');
                $("#"+defaultValue).attr('placeholder', '请输入默认值(邮箱)');
            }else if(value==='url'){
                $("#"+defaultValue).attr('lay-verify', 'url');
                $("#"+defaultValue).attr('placeholder', '请输入默认值(url)');
            }else if(value==='identity'){
                $("#"+defaultValue).attr('lay-verify', 'identity');
                $("#"+defaultValue).attr('placeholder', '请输入默认值(身份证)');
            }else{
                $("#"+defaultValue).attr('lay-verify', '');
                $("#"+defaultValue).attr('placeholder', '请输入默认值');
            }
            form.render();
        },

注意事项:html模块类型的value值要和后端枚举类的值一致!!!

2.展示自定义字段(编辑则展示字段和value值)

进入模块管理页面前首先我们通过getCustomFieldValue这个方法获取到当前模块的自定义字段和value值(编辑页面需要获取到value值,新增页面不需要,所以新增页面不传业务id),这里以新增为例。

代码如下:

List> customFieldValue = this.customFieldsService.getCustomFieldValue("",CustomTypeConstants.模块类型的值);
mv.addObject("customFieldValue", customFieldValue);

然后因为不同页面的宽高是不一样的,所以自定义字段的展示我这里根据不同的尺寸进行了通用的封装。

css代码如下:

 .head{
            padding: 10px;
            width: 90%;
            margin: auto;
            border-radius: 10px;
            box-shadow: 0 4px 6px #0c1f500a, 0 0 0 1px #e6eaf0;
            background: #FFFFFF;
        }

 html代码如下:

自定义字段

 js代码如下:

/**
         * 展示自定义字段
         * @param elemId 容器id
         * @param customFieldValue 自定义字段列表
         * @param showFlag 是否可编辑
         */
        showCustomFieldValue: function (elemId, customFieldValue,showFlag) {
            let pageWidth = window.innerWidth;
            let pageLength;
            let width;
            if(obj.isEmpty(showFlag)){
                showFlag = '';
            }
            if(pageWidth>1200){
                pageLength = pageWidth*0.2;
                width = 500;
            }else if(pageWidth>900&&pageWidth<=1200){
                pageLength = pageWidth*0.15;
                width = 350;
            }else{
                pageLength = pageWidth*0.1;
                width = 300;
            }
            for (let i = 0; i < customFieldValue.length; i++) {
                let customValue;
                if(obj.isNotEmpty(customFieldValue[i].value)){
                    customValue = customFieldValue[i].value;
                }else{
                    customValue = customFieldValue[i].default_value;
                }
                if(customFieldValue[i].type==='archives'){
                    pageLength = 0;
                    width = 200;
                }
                let str = '';
                if (customFieldValue[i].field_format === 'list') {
                    let options = '';
                    let array = customFieldValue[i].possible_values.split(',');
                    for (let j = 0; j < array.length; j++) {
                        if (array[j] === customValue) {
                            options += ''
                        } else {
                            options += ''
                        }
                    }
                    str = '';
                } else if (customFieldValue[i].field_format === 'int') {
                    str = '';
                } else if (customFieldValue[i].field_format === 'date') {
                    str = '';
                } else if (customFieldValue[i].field_format === 'phone') {
                    str = '';
                } else if (customFieldValue[i].field_format === 'email') {
                    str = '';
                } else if (customFieldValue[i].field_format === 'url') {
                    str = '';
                } else if (customFieldValue[i].field_format === 'identity') {
                    str = '';
                } else if (customFieldValue[i].field_format === 'text') {
                    str = '';
                } else {
                    str ='';
                }
                let iHtml = ' 
' + '' + '
' + str + '
' + '
'; $("#" + elemId).append(iHtml); if (customFieldValue[i].field_format === 'date') { laydate.render({ elem: '#date' + i //或 elem: document.getElementById('test')、elem: lay('#test') 等 , type: 'date' }); } } form.render('select'); },

3.添加自定义字段value值

首先从html中获取到id为custom的div元素,然后对里面的字段和value进行解析,最后通过ajax传到后端进行保存。

代码如下:

  /**
         * 添加自定义字段的value
         * @param elem 容器元素
         * @param type 模块类型
         * @param customizedId 业务数据id
         * @returns {boolean}
         */
        addCustomValue: function (elem, type, customizedId) {
            let value = {};
            let field = {};
            elem.find('label').each(function () {
                value[$(this).find('span').attr("value")] = $(this).siblings().children().val();
            });
            field.value = value;
            field.customizedType = type;
            field.customizedId = customizedId;
            admin.req({
                type: "post",
                url: ctxPath + 'custom/addCustomValue',
                data: JSON.stringify(field),
                dataType: "json",
                contentType: 'application/json;charset=utf-8',
                success: function (result) {
                    let data = result.data;
                    if (data === obj.webConst.SUCCESS) {
                        //layer.msg('添加成功!', {icon: 6});
                    } else {
                        layer.msg('添加自定义字段value值失败!', {icon: 5, shift: 6});
                    }
                }, error: function () {
                    layer.alert('请求失败');
                }
            });
        },

总结

此功能实现了可在不同页面实现自定义字段,字段的格式可以根据需要自行配置,并提供了列表格式输入可能的值,会以下拉框的形式展示可能的值,也提供了默认值的配置,极大的方便了用户个性化的需求。

你可能感兴趣的:(java,java,mybatis,layui,数据库,spring,boot)