【业务功能篇28】Springboot+mybatisPlus 实现不同用户自定义表单列数显示

业务场景: 当前有个需求,在一个问题表单中,一般我们的列都是固定的展示哪些列,那么现在用户需要自定义自己的一个列头,不同用户关注的表单字段信息不一样,比如用户A关注问题细节,只想展示几列字段,而用户B关注整体,那么就想展示全部十几列字段。

解决思路:我们前端会设置按钮,展示问题表单全部字段,每个字段左侧有个方框勾选,去给用户勾选自己想展示的列,勾选了十列,就展示十个列数据。

这里不同用户的判断,前提是我们系统中是做好了SSO单点登录,前端发起的每个接口都会先经过过滤器,判断当前用户是否登录,如果登录了,浏览器就会保存用户相关信息在cookies中,后续每次请求,都会带上这个信息,后端拿到信息可以判断当前用户登录,并且返回完整用户信息,这里不展开用户信息接口,只展开对数据表单列头的控制

思路解析:

1.一开始是默认展示整个表单字段列信息,返回给前端,然后在前端配置按钮,进行勾选,保存后,表格字段就会刷新成被勾选的字段列展示,再点击按钮再修改,那么就会再刷新展示对应的字段列

2.从需求上可以看出,我们需要在后台保存每个用户自定义勾选了哪些字段,这里就有两个核心字段,当然表默认都要有个自增id,以及插入数据的创建时间;另外用户还可以多次修改勾选的字段,修改时间字段我们也可以加上; 表中还有一个标识字段data_type, 主要是当前业务有两个问题表单管理,一个是前端问题单 一个是后端问题单,两个前台页面,都有相同需求,所以增加一个字段来标识0,1 ; 判断是哪个页面设置的。

3.所以应该需要设计两个接口:

一个是返回当前用户选择的自定义列信息

一个是更新当前用户选择的自定义列信息


前端传参类: 保存用户勾选字段数据封装成类

  • 关键字段:checkedCol   用逗号分割拼接多个勾选的列头信息,  比如 "问题描述,发生时间"
  • 该类与DistributionWarnCol类是相同一致的,只不过代码规范了,两个页面表单,传递参数用两个不同类接收,但实际属性都是一样的
package com.xxx.model;

import java.util.Objects;
import java.io.Serializable;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;




 @JsonIgnoreProperties(ignoreUnknown = true)

public class ProdProblemWarnCol implements Serializable {
    private static final long serialVersionUID = 1L;
    
    @JsonProperty("checkedCol")
    private String checkedCol = null;
    
    @JsonProperty("userCn")
    private String userCn = null;
    
    @JsonProperty("DataType")
    private String dataType = null;
    
    public ProdProblemWarnCol() {
        super();
    } 
    
    /**
     * 配置展示字段
    **/
    public String getCheckedCol() {
        return checkedCol;
    }

    public void setCheckedCol(String checkedCol) {
        this.checkedCol = checkedCol;
    }
    
    /**
     * 用户
    **/
    public String getUserCn() {
        return userCn;
    }

    public void setUserCn(String userCn) {
        this.userCn = userCn;
    }
    
    /**
     * 类型,用于区分页面,0:前端问题,1:后端问题
    **/
    public String getDataType() {
        return dataType;
    }

    public void setDataType(String dataType) {
        this.dataType = dataType;
    }
    
      
    
      
    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        
        
        ProdProblemWarnCol prodProblemWarnCol = (ProdProblemWarnCol) o;
        return Objects.equals(this.checkedCol,
                prodProblemWarnCol.checkedCol)
                && Objects.equals(this.userCn,
                prodProblemWarnCol.userCn)
                && Objects.equals(this.dataType,
                prodProblemWarnCol.dataType);
    } 
    
      
    @Override
    public int hashCode() {
        return Objects.hash(checkedCol
                , userCn
                , dataType);
    } 
    
       

      
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("class ProdProblemWarnCol { ");
        
        sb.append("  checkedCol: ").append(checkedCol).append(", ");
        sb.append("  userCn: ").append(userCn).append(", ");
        sb.append("  dataType: ").append(dataType).append(", ");
        sb.append("} ");
        return sb.toString();
      }
}

表实体类:

@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@NoArgsConstructor
@TableName("col_f")
public class MtDistributionColF implements Serializable {

    private static final long serialVersionUID = 1L;

    @TableId(value = "ID", type = IdType.AUTO)
    private Integer id;

    /**
     * 字段配置,英文逗号分隔
     */
    @TableField("CHECKED_COL")
    private String checkedCol;

    /**
     * 用户
     */
    @TableField("USER_CN")
    private String userCn;

    /**
     * 类型,用于区分页面,0:前端问题单表,1:后端问题单表
     */
    @TableField("DATA_TYPE")
    private String dataType;

    /**
     * 创建时间
     */
    @TableField("CREATION_DATE")
    private Date creationDate;

    /**
     * 更新时间
     */
    @TableField("LAST_UPDATE_DATE")
    private Date lastUpdateDate;


}

controller层

@RestController
@RequestMapping(value = "/ProdProblemWarn", produces = {"application/json;charset=UTF-8"})
@Validated
public class ProdProblemWarnController { 
    @Autowired(required=false) 
    private ProdProblemWarnService delegate;  


   @RequestMapping(
    		value = "/getUserCol", 
    		produces = { "application/json" }, 
    		method = RequestMethod.GET)
    public ResponseVo getUserCol( @RequestParam(value = "user", required = true) String user) 
            throws ServiceException {
    	    
		return delegate.getUserCol(user);
    }


    @RequestMapping(
    		value = "/saveUserCol", 
    		produces = { "application/json" }, 
    		method = RequestMethod.POST)
    public ResponseVo saveUserCol(@RequestBody ProdProblemWarnCol warnCol) 
            throws ServiceException {
    	    
		return delegate.saveUserCol(warnCol);
    }

}

service层 接口 

public interface ProdProblemWarnService {
    ResponseVo getUserCol(String user);

    ResponseVo saveUserCol(ProdProblemWarnCol warnCol);

}

service层 接口实现类

@Slf4j
public class ProdProblemWarnServiceImpl implements ProdProblemWarnService {

    @Resource
    private FieldConfigService FieldConfigService;

    @Override
    public ResponseVo getUserCol(String user) {

        //调用字段配置服务接口,把前端传递的user用户信息传递,查询该用户的勾选配置字段
        return ResponseUtils.successResponse(FieldConfigService.getUserCol(user, "1"), "获取数据成功");
    }

    @Override
    public ResponseVo saveUserCol(ProdProblemWarnCol warnCol) {

        //创建一个实体类接收数据 由于这个saveUserCol接口是最先开发的前端问题的配置字段,
        //为了规范 这里后端问题配置字段 另外用ProdProblemWarnCol 实体类接收了,实际上与
        //DistributionWarnCol类是一样的属性
        DistributionWarnCol param = new DistributionWarnCol();

        //将对象拷贝给param 然后传递到 FieldConfigService.saveUserCol入参
        MyBeanUtils.shallowCopy(warnCol, param);
        param.setDataType("1");
        FieldConfigService.saveUserCol(param);
        return ResponseUtils.successResponse(null, "保存数据成功");
    }

}

 dao层 接口

public interface FieldConfigService extends IService {

    MtDistributionColF getUserCol(String user, String dataType);

    void saveUserCol(DistributionWarnCol warnCol);

}

dao层 接口实现类

@Slf4j
@Component
public class MatWarnFieldConfigServiceImpl extends ServiceImpl
    implements FieldConfigService {

    @Override
    public MtDistributionColF getUserCol(String user, String dataType) {
        //查询 前端传递的用户 对应的一条配置字段记录 一个用户一个datatype页面仅有一条记录
        QueryWrapper wrapper = new QueryWrapper<>();
        wrapper.eq("USER_CN", user);
        wrapper.eq("Data_TYPE", dataType);
        return baseMapper.selectOne(wrapper);
    }

    @Override
    public void saveUserCol(DistributionWarnCol warnCol) {
        QueryWrapper wrapper = new QueryWrapper<>();
    
        //先查询表中是否存在对应用户,表单页面类型的记录count
        wrapper.eq("USER_CN", warnCol.getUserCn());
        wrapper.eq("DATA_TYPE", warnCol.getDataType());
        Long count = baseMapper.selectCount(wrapper);

        //创建对应表实体类对象 将前端传参对象拷贝过去 
        MtDistributionColF target = new MtDistributionColF();
        MyBeanUtils.shallowCopy(warnCol, target);

        //如果表中存在有该用户的一条记录 那么就进行更新操作 刷新更新时间字段
        if (count > 0) {
            LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(MtDistributionColF::getUserCn, warnCol.getUserCn())
                .set(MtDistributionColF::getCheckedCol, warnCol.getCheckedCol())
                .set(MtDistributionColF::getLastUpdateDate, new Date());
            baseMapper.update(null, updateWrapper);
        } else {

            //如果表中不存在,那么就插入target 转换好的对象 把创建时间也添加系统时间
            target.setCreationDate(new Date());
            target.setLastUpdateDate(new Date());
            baseMapper.insert(target);
        }
    }

}

dao层 mapper接口

没有需要自定义的接口,但是也是需要定义的,规范需要 在实现类中集成的 泛型对象就需要传递mapper接口

@Mapper
public interface MtDistributionColMapper extends BaseMapper {

}

你可能感兴趣的:(Spring,boot,Java,spring,boot,后端,java)