那么首先说一下怎么实现回显,一般状态回显没有用关联对象的话,会比较简单,一般回显的时候一般是已经带有id去回选了,回走根据id查对象,不过有一些回显就比较特殊,如使用字典对象,或已经关联了其他对象,相对操作会没那么简单,但实际上并不难,那么用thymeleaf怎么实现状态回显呢?首先要知道几个标签,当然也可以使用前端的方法获取就是获取下表的方式,我们这里着重讲使用thymeleaf动态标签的方式获取。
th:each, th:value, th:field, th:text, th:selected, th:checked
分别是遍历,获取值,填充文本 ,选择复选框元素,选中单选框的值
首先看看实体类:
讲讲实现这个回显要注意的一些问题,一个注意标签的级别,获取对象的优先级。首先这个表单对象实际上是客户这个对象的,所以获取客户对象应该在form标签就获取,这样才是合理的,name对应着后端对象的属性(因为一般修改接收的是一个整体对象,并不会对具体属性赋值绑定,所以如果这里属性和实体类映射的属性不一致则会出现前端发出了请求,后端接收不到的情况),其次就是知道th:selected标签表示选择该值的下拉框,实际上后端关联的逻辑也是两个对象相关联的id相同,这里使用后端java代码处理会比较而使用着这个标签比较th:selected="${mtCustomer.cstProjectId eq mtProjectinfo.projectId}"
,画龙点睛吧,可以说是,因为是在同一级标签,所以即使现在遍历集合之前,也是先执行的遍历,然后执行下拉框填充,th:value,标志每一个选项option的值,从数据库直接取出的,可以直接回填,不需要处理,很好,很方便,同时会执行th:text文本回填,回填的值也是数据库的值,可以避免前端插入下标值和数据库属性名不一致的问题,再则执行具体的对象的id比较,就会初始加载的时候就选中该id的下拉框,完美!!
输入框较为简单,还是以上面的案例讲解:
在form表单就获取客户对象,而在文本框中使用th:filed
效果如下:
当然其实两个都写测试是不好的,因为有可能有时候会属性名对应复制黏贴忘记修改读取的对应的属性,导致一个bug的出现,当然细心点,多仔细看数据库还有查询的ajax以及修改展示部分的name啊等等的属性,就可以避免这个问题!!
th:field限制较多,我们可以看见当我们使用th:field的时候标签是没指定name属性的,但是我们却可以成功获取到后端的数据,实际上thymeleaf里的th:field等同于th:name和th:value,所以在同一级别的标签内或者说要映射属性的同一个区域内不要同时出现th:value和th:field
,会造成冲突报错。所以有时候因为同级的限制已经有th:value所以在单选框里我们就不能用th:field,还有一种情况是我们的下拉框加了一个不是动态获取的,如上面的一个空的option的写着请选择的时候就会出现就回显一直是显示那个请选择的下拉框,无法智能选中值。
看看前端编写:
我们点进@dict可以快速到,指定的service注解值为dict的类路径下,这也是thymeleaf的特性,很强大。
先展示一下小技巧:
然后我们看看实体字典类设定里两个类:一个是类型类,一个是具体数据类
简单介绍一下字典,字典类用于存储比较固定的值,一些系统参数等等,变化性不大的数据,通过分类型以及数据值,快速定位取值,一般单个类型的数据量并不大,对性能影响不大,且省事,不用为具体类的具体属性专门写一个dto或者vo对象,以及查询方法等等来回显,会轻松很多,当然这个适合一些较为固定的值会更合适点,像上面的案例的项目名称,因为项目的变化性,随时会有增减项目,可能直接使用上面那样获取会好一点,当然也可以使用字典,不然就要编写不同字典的一些调度任务或者是手动同步了。
我们看见上面的前端注释里有.default的获取也是通过实体类实现的,default的话使用该字段的默认值。贴上相关的源码吧还是:
package com.ruoyi.common.core.domain.entity;
import javax.validation.constraints.*;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.annotation.Excel.ColumnType;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.BaseEntity;
/**
* 字典数据表 sys_dict_data
*
* @author ruoyi
*/
public class SysDictData extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 字典编码 */
@Excel(name = "字典编码", cellType = ColumnType.NUMERIC)
private Long dictCode;
/** 字典排序 */
@Excel(name = "字典排序", cellType = ColumnType.NUMERIC)
private Long dictSort;
/** 字典标签 */
@Excel(name = "字典标签")
private String dictLabel;
/** 字典键值 */
@Excel(name = "字典键值")
private String dictValue;
/** 字典类型 */
@Excel(name = "字典类型")
private String dictType;
/** 样式属性(其他样式扩展) */
@Excel(name = "字典样式")
private String cssClass;
/** 表格字典样式 */
private String listClass;
/** 是否默认(Y是 N否) */
@Excel(name = "是否默认", readConverterExp = "Y=是,N=否")
private String isDefault;
/** 状态(0正常 1停用) */
@Excel(name = "状态", readConverterExp = "0=正常,1=停用")
private String status;
public Long getDictCode()
{
return dictCode;
}
public void setDictCode(Long dictCode)
{
this.dictCode = dictCode;
}
public Long getDictSort()
{
return dictSort;
}
public void setDictSort(Long dictSort)
{
this.dictSort = dictSort;
}
@NotBlank(message = "字典标签不能为空")
@Size(min = 0, max = 100, message = "字典标签长度不能超过100个字符")
public String getDictLabel()
{
return dictLabel;
}
public void setDictLabel(String dictLabel)
{
this.dictLabel = dictLabel;
}
@NotBlank(message = "字典键值不能为空")
@Size(min = 0, max = 100, message = "字典键值长度不能超过100个字符")
public String getDictValue()
{
return dictValue;
}
public void setDictValue(String dictValue)
{
this.dictValue = dictValue;
}
@NotBlank(message = "字典类型不能为空")
@Size(min = 0, max = 100, message = "字典类型长度不能超过100个字符")
public String getDictType()
{
return dictType;
}
public void setDictType(String dictType)
{
this.dictType = dictType;
}
@Size(min = 0, max = 100, message = "样式属性长度不能超过100个字符")
public String getCssClass()
{
return cssClass;
}
public void setCssClass(String cssClass)
{
this.cssClass = cssClass;
}
public String getListClass()
{
return listClass;
}
public void setListClass(String listClass)
{
this.listClass = listClass;
}
public boolean getDefault()
{
return UserConstants.YES.equals(this.isDefault) ? true : false;
}
public String getIsDefault()
{
return isDefault;
}
public void setIsDefault(String isDefault)
{
this.isDefault = isDefault;
}
public String getStatus()
{
return status;
}
public void setStatus(String status)
{
this.status = status;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("dictCode", getDictCode())
.append("dictSort", getDictSort())
.append("dictLabel", getDictLabel())
.append("dictValue", getDictValue())
.append("dictType", getDictType())
.append("cssClass", getCssClass())
.append("listClass", getListClass())
.append("isDefault", getIsDefault())
.append("status", getStatus())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("remark", getRemark())
.toString();
}
}
package com.ruoyi.common.core.domain.entity;
import javax.validation.constraints.*;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.annotation.Excel.ColumnType;
import com.ruoyi.common.core.domain.BaseEntity;
/**
* 字典类型表 sys_dict_type
*
* @author ruoyi
*/
public class SysDictType extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 字典主键 */
@Excel(name = "字典主键", cellType = ColumnType.NUMERIC)
private Long dictId;
/** 字典名称 */
@Excel(name = "字典名称")
private String dictName;
/** 字典类型 */
@Excel(name = "字典类型")
private String dictType;
/** 状态(0正常 1停用) */
@Excel(name = "状态", readConverterExp = "0=正常,1=停用")
private String status;
public Long getDictId()
{
return dictId;
}
public void setDictId(Long dictId)
{
this.dictId = dictId;
}
@NotBlank(message = "字典名称不能为空")
@Size(min = 0, max = 100, message = "字典类型名称长度不能超过100个字符")
public String getDictName()
{
return dictName;
}
public void setDictName(String dictName)
{
this.dictName = dictName;
}
@NotBlank(message = "字典类型不能为空")
@Size(min = 0, max = 100, message = "字典类型类型长度不能超过100个字符")
public String getDictType()
{
return dictType;
}
public void setDictType(String dictType)
{
this.dictType = dictType;
}
public String getStatus()
{
return status;
}
public void setStatus(String status)
{
this.status = status;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("dictId", getDictId())
.append("dictName", getDictName())
.append("dictType", getDictType())
.append("status", getStatus())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("remark", getRemark())
.toString();
}
}
package com.ruoyi.system.mapper;
import java.util.List;
import com.ruoyi.common.core.domain.entity.SysDictType;
/**
* 字典表 数据层
*
* @author ruoyi
*/
public interface SysDictTypeMapper
{
/**
* 根据条件分页查询字典类型
*
* @param dictType 字典类型信息
* @return 字典类型集合信息
*/
public List<SysDictType> selectDictTypeList(SysDictType dictType);
/**
* 根据所有字典类型
*
* @return 字典类型集合信息
*/
public List<SysDictType> selectDictTypeAll();
/**
* 根据字典类型ID查询信息
*
* @param dictId 字典类型ID
* @return 字典类型
*/
public SysDictType selectDictTypeById(Long dictId);
/**
* 根据字典类型查询信息
*
* @param dictType 字典类型
* @return 字典类型
*/
public SysDictType selectDictTypeByType(String dictType);
/**
* 通过字典ID删除字典信息
*
* @param dictId 字典ID
* @return 结果
*/
public int deleteDictTypeById(Long dictId);
/**
* 批量删除字典类型
*
* @param ids 需要删除的数据
* @return 结果
*/
public int deleteDictTypeByIds(Long[] ids);
/**
* 新增字典类型信息
*
* @param dictType 字典类型信息
* @return 结果
*/
public int insertDictType(SysDictType dictType);
/**
* 修改字典类型信息
*
* @param dictType 字典类型信息
* @return 结果
*/
public int updateDictType(SysDictType dictType);
/**
* 校验字典类型称是否唯一
*
* @param dictType 字典类型
* @return 结果
*/
public SysDictType checkDictTypeUnique(String dictType);
}
package com.ruoyi.system.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import com.ruoyi.common.core.domain.entity.SysDictData;
/**
* 字典表 数据层
*
* @author ruoyi
*/
public interface SysDictDataMapper
{
/**
* 根据条件分页查询字典数据
*
* @param dictData 字典数据信息
* @return 字典数据集合信息
*/
public List<SysDictData> selectDictDataList(SysDictData dictData);
/**
* 根据字典类型查询字典数据
*
* @param dictType 字典类型
* @return 字典数据集合信息
*/
public List<SysDictData> selectDictDataByType(String dictType);
/**
* 根据字典类型和字典键值查询字典数据信息
*
* @param dictType 字典类型
* @param dictValue 字典键值
* @return 字典标签
*/
public String selectDictLabel(@Param("dictType") String dictType, @Param("dictValue") String dictValue);
/**
* 根据字典数据ID查询信息
*
* @param dictCode 字典数据ID
* @return 字典数据
*/
public SysDictData selectDictDataById(Long dictCode);
/**
* 查询字典数据
*
* @param dictType 字典类型
* @return 字典数据
*/
public int countDictDataByType(String dictType);
/**
* 通过字典ID删除字典数据信息
*
* @param dictCode 字典数据ID
* @return 结果
*/
public int deleteDictDataById(Long dictCode);
/**
* 批量删除字典数据
*
* @param ids 需要删除的数据
* @return 结果
*/
public int deleteDictDataByIds(String[] ids);
/**
* 新增字典数据信息
*
* @param dictData 字典数据信息
* @return 结果
*/
public int insertDictData(SysDictData dictData);
/**
* 修改字典数据信息
*
* @param dictData 字典数据信息
* @return 结果
*/
public int updateDictData(SysDictData dictData);
/**
* 同步修改字典类型
*
* @param oldDictType 旧字典类型
* @param newDictType 新旧字典类型
* @return 结果
*/
public int updateDictDataType(@Param("oldDictType") String oldDictType, @Param("newDictType") String newDictType);
}
<mapper namespace="com.ruoyi.system.mapper.SysDictDataMapper">
<resultMap type="SysDictData" id="SysDictDataResult">
<id property="dictCode" column="dict_code" />
<result property="dictSort" column="dict_sort" />
<result property="dictLabel" column="dict_label" />
<result property="dictValue" column="dict_value" />
<result property="dictType" column="dict_type" />
<result property="cssClass" column="css_class" />
<result property="listClass" column="list_class" />
<result property="isDefault" column="is_default" />
<result property="status" column="status" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
resultMap>
<sql id="selectDictDataVo">
select dict_code, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, status, create_by, create_time, remark
from sys_dict_data
sql>
<select id="selectDictDataList" parameterType="SysDictData" resultMap="SysDictDataResult">
<include refid="selectDictDataVo"/>
<where>
<if test="dictType != null and dictType != ''">
AND dict_type = #{dictType}
if>
<if test="dictLabel != null and dictLabel != ''">
AND dict_label like concat('%', #{dictLabel}, '%')
if>
<if test="status != null and status != ''">
AND status = #{status}
if>
where>
select>
<select id="selectDictDataByType" parameterType="SysDictData" resultMap="SysDictDataResult">
<include refid="selectDictDataVo"/>
where status = '0' and dict_type = #{dictType} order by dict_sort asc
select>
<select id="selectDictLabel" resultType="String">
select dict_label from sys_dict_data
where dict_type = #{dictType} and dict_value = #{dictValue}
select>
<select id="selectDictDataById" parameterType="Long" resultMap="SysDictDataResult">
<include refid="selectDictDataVo"/>
where dict_code = #{dictCode}
select>
<select id="countDictDataByType" resultType="Integer">
select count(1) from sys_dict_data where dict_type=#{dictType}
select>
<delete id="deleteDictDataById" parameterType="Long">
delete from sys_dict_data where dict_code = #{dictCode}
delete>
<delete id="deleteDictDataByIds" parameterType="String">
delete from sys_dict_data where dict_code in
<foreach collection="array" item="dictCode" open="(" separator="," close=")">
#{dictCode}
foreach>
delete>
<update id="updateDictData" parameterType="SysDictData">
update sys_dict_data
<set>
<if test="dictSort != null">dict_sort = #{dictSort},if>
<if test="dictLabel != null and dictLabel != ''">dict_label = #{dictLabel},if>
<if test="dictValue != null and dictValue != ''">dict_value = #{dictValue},if>
<if test="dictType != null and dictType != ''">dict_type = #{dictType},if>
<if test="cssClass != null">css_class = #{cssClass},if>
<if test="listClass != null">list_class = #{listClass},if>
<if test="isDefault != null and isDefault != ''">is_default = #{isDefault},if>
<if test="status != null">status = #{status},if>
<if test="remark != null">remark = #{remark},if>
<if test="updateBy != null and updateBy != ''">update_by = #{updateBy},if>
update_time = sysdate()
set>
where dict_code = #{dictCode}
update>
<update id="updateDictDataType" parameterType="String">
update sys_dict_data set dict_type = #{newDictType} where dict_type = #{oldDictType}
update>
<insert id="insertDictData" parameterType="SysDictData">
insert into sys_dict_data(
<if test="dictSort != null">dict_sort,if>
<if test="dictLabel != null and dictLabel != ''">dict_label,if>
<if test="dictValue != null and dictValue != ''">dict_value,if>
<if test="dictType != null and dictType != ''">dict_type,if>
<if test="cssClass != null and cssClass != ''">css_class,if>
<if test="listClass != null and listClass != ''">list_class,if>
<if test="isDefault != null and isDefault != ''">is_default,if>
<if test="status != null">status,if>
<if test="remark != null and remark != ''">remark,if>
<if test="createBy != null and createBy != ''">create_by,if>
create_time
)values(
<if test="dictSort != null">#{dictSort},if>
<if test="dictLabel != null and dictLabel != ''">#{dictLabel},if>
<if test="dictValue != null and dictValue != ''">#{dictValue},if>
<if test="dictType != null and dictType != ''">#{dictType},if>
<if test="cssClass != null and cssClass != ''">#{cssClass},if>
<if test="listClass != null and listClass != ''">#{listClass},if>
<if test="isDefault != null and isDefault != ''">#{isDefault},if>
<if test="status != null">#{status},if>
<if test="remark != null and remark != ''">#{remark},if>
<if test="createBy != null and createBy != ''">#{createBy},if>
sysdate()
)
insert>
mapper>
<mapper namespace="com.ruoyi.system.mapper.SysDictTypeMapper">
<resultMap type="SysDictType" id="SysDictTypeResult">
<id property="dictId" column="dict_id" />
<result property="dictName" column="dict_name" />
<result property="dictType" column="dict_type" />
<result property="status" column="status" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
resultMap>
<sql id="selectDictTypeVo">
select dict_id, dict_name, dict_type, status, create_by, create_time, remark
from sys_dict_type
sql>
<select id="selectDictTypeList" parameterType="SysDictType" resultMap="SysDictTypeResult">
<include refid="selectDictTypeVo"/>
<where>
<if test="dictName != null and dictName != ''">
AND dict_name like concat('%', #{dictName}, '%')
if>
<if test="status != null and status != ''">
AND status = #{status}
if>
<if test="dictType != null and dictType != ''">
AND dict_type like concat('%', #{dictType}, '%')
if>
<if test="params.beginTime != null and params.beginTime != ''">
and date_format(create_time,'%y%m%d') >= date_format(#{params.beginTime},'%y%m%d')
if>
<if test="params.endTime != null and params.endTime != ''">
and date_format(create_time,'%y%m%d') <= date_format(#{params.endTime},'%y%m%d')
if>
where>
select>
<select id="selectDictTypeAll" resultMap="SysDictTypeResult">
<include refid="selectDictTypeVo"/>
select>
<select id="selectDictTypeById" parameterType="Long" resultMap="SysDictTypeResult">
<include refid="selectDictTypeVo"/>
where dict_id = #{dictId}
select>
<select id="selectDictTypeByType" parameterType="String" resultMap="SysDictTypeResult">
<include refid="selectDictTypeVo"/>
where dict_type = #{dictType}
select>
<select id="checkDictTypeUnique" parameterType="String" resultMap="SysDictTypeResult">
<include refid="selectDictTypeVo"/>
where dict_type = #{dictType} limit 1
select>
<delete id="deleteDictTypeById" parameterType="Long">
delete from sys_dict_type where dict_id = #{dictId}
delete>
<delete id="deleteDictTypeByIds" parameterType="Long">
delete from sys_dict_type where dict_id in
<foreach collection="array" item="dictId" open="(" separator="," close=")">
#{dictId}
foreach>
delete>
<update id="updateDictType" parameterType="SysDictType">
update sys_dict_type
<set>
<if test="dictName != null and dictName != ''">dict_name = #{dictName},if>
<if test="dictType != null and dictType != ''">dict_type = #{dictType},if>
<if test="status != null">status = #{status},if>
<if test="remark != null">remark = #{remark},if>
<if test="updateBy != null and updateBy != ''">update_by = #{updateBy},if>
update_time = sysdate()
set>
where dict_id = #{dictId}
update>
<insert id="insertDictType" parameterType="SysDictType">
insert into sys_dict_type(
<if test="dictName != null and dictName != ''">dict_name,if>
<if test="dictType != null and dictType != ''">dict_type,if>
<if test="status != null">status,if>
<if test="remark != null and remark != ''">remark,if>
<if test="createBy != null and createBy != ''">create_by,if>
create_time
)values(
<if test="dictName != null and dictName != ''">#{dictName},if>
<if test="dictType != null and dictType != ''">#{dictType},if>
<if test="status != null">#{status},if>
<if test="remark != null and remark != ''">#{remark},if>
<if test="createBy != null and createBy != ''">#{createBy},if>
sysdate()
)
insert>
mapper>
package com.ruoyi.system.service;
import java.util.List;
import com.ruoyi.common.core.domain.entity.SysDictData;
/**
* 字典 业务层
*
* @author ruoyi
*/
public interface ISysDictDataService
{
/**
* 根据条件分页查询字典数据
*
* @param dictData 字典数据信息
* @return 字典数据集合信息
*/
public List<SysDictData> selectDictDataList(SysDictData dictData);
/**
* 根据字典类型和字典键值查询字典数据信息
*
* @param dictType 字典类型
* @param dictValue 字典键值
* @return 字典标签
*/
public String selectDictLabel(String dictType, String dictValue);
/**
* 根据字典数据ID查询信息
*
* @param dictCode 字典数据ID
* @return 字典数据
*/
public SysDictData selectDictDataById(Long dictCode);
/**
* 批量删除字典数据
*
* @param ids 需要删除的数据
* @return 结果
*/
public int deleteDictDataByIds(String ids);
/**
* 新增保存字典数据信息
*
* @param dictData 字典数据信息
* @return 结果
*/
public int insertDictData(SysDictData dictData);
/**
* 修改保存字典数据信息
*
* @param dictData 字典数据信息
* @return 结果
*/
public int updateDictData(SysDictData dictData);
}
package com.ruoyi.system.service;
import java.util.List;
import com.ruoyi.common.core.domain.Ztree;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.domain.entity.SysDictType;
/**
* 字典 业务层
*
* @author ruoyi
*/
public interface ISysDictTypeService
{
/**
* 根据条件分页查询字典类型
*
* @param dictType 字典类型信息
* @return 字典类型集合信息
*/
public List<SysDictType> selectDictTypeList(SysDictType dictType);
/**
* 根据所有字典类型
*
* @return 字典类型集合信息
*/
public List<SysDictType> selectDictTypeAll();
/**
* 根据字典类型查询字典数据
*
* @param dictType 字典类型
* @return 字典数据集合信息
*/
public List<SysDictData> selectDictDataByType(String dictType);
/**
* 根据字典类型ID查询信息
*
* @param dictId 字典类型ID
* @return 字典类型
*/
public SysDictType selectDictTypeById(Long dictId);
/**
* 根据字典类型查询信息
*
* @param dictType 字典类型
* @return 字典类型
*/
public SysDictType selectDictTypeByType(String dictType);
/**
* 批量删除字典类型
*
* @param ids 需要删除的数据
* @return 结果
* @throws Exception 异常
*/
public int deleteDictTypeByIds(String ids);
/**
* 清空缓存数据
*/
public void clearCache();
/**
* 新增保存字典类型信息
*
* @param dictType 字典类型信息
* @return 结果
*/
public int insertDictType(SysDictType dictType);
/**
* 修改保存字典类型信息
*
* @param dictType 字典类型信息
* @return 结果
*/
public int updateDictType(SysDictType dictType);
/**
* 校验字典类型称是否唯一
*
* @param dictType 字典类型
* @return 结果
*/
public String checkDictTypeUnique(SysDictType dictType);
/**
* 查询字典类型树
*
* @param dictType 字典类型
* @return 所有字典类型
*/
public List<Ztree> selectDictTree(SysDictType dictType);
}
package com.ruoyi.system.service.impl;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.Ztree;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.domain.entity.SysDictType;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.exception.BusinessException;
import com.ruoyi.common.utils.DictUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.mapper.SysDictDataMapper;
import com.ruoyi.system.mapper.SysDictTypeMapper;
import com.ruoyi.system.service.ISysDictTypeService;
/**
* 字典 业务层处理
*
* @author ruoyi
*/
@Service
public class SysDictTypeServiceImpl implements ISysDictTypeService
{
@Autowired
private SysDictTypeMapper dictTypeMapper;
@Autowired
private SysDictDataMapper dictDataMapper;
/**
* 项目启动时,初始化字典到缓存
*/
@PostConstruct
public void init()
{
List<SysDictType> dictTypeList = dictTypeMapper.selectDictTypeAll();
for (SysDictType dictType : dictTypeList)
{
List<SysDictData> dictDatas = dictDataMapper.selectDictDataByType(dictType.getDictType());
DictUtils.setDictCache(dictType.getDictType(), dictDatas);
}
}
/**
* 根据条件分页查询字典类型
*
* @param dictType 字典类型信息
* @return 字典类型集合信息
*/
@Override
public List<SysDictType> selectDictTypeList(SysDictType dictType)
{
return dictTypeMapper.selectDictTypeList(dictType);
}
/**
* 根据所有字典类型
*
* @return 字典类型集合信息
*/
@Override
public List<SysDictType> selectDictTypeAll()
{
return dictTypeMapper.selectDictTypeAll();
}
/**
* 根据字典类型查询字典数据
*
* @param dictType 字典类型
* @return 字典数据集合信息
*/
@Override
public List<SysDictData> selectDictDataByType(String dictType)
{
List<SysDictData> dictDatas = DictUtils.getDictCache(dictType);
if (StringUtils.isNotEmpty(dictDatas))
{
return dictDatas;
}
dictDatas = dictDataMapper.selectDictDataByType(dictType);
if (StringUtils.isNotEmpty(dictDatas))
{
DictUtils.setDictCache(dictType, dictDatas);
return dictDatas;
}
return null;
}
/**
* 根据字典类型ID查询信息
*
* @param dictId 字典类型ID
* @return 字典类型
*/
@Override
public SysDictType selectDictTypeById(Long dictId)
{
return dictTypeMapper.selectDictTypeById(dictId);
}
/**
* 根据字典类型查询信息
*
* @param dictType 字典类型
* @return 字典类型
*/
@Override
public SysDictType selectDictTypeByType(String dictType)
{
return dictTypeMapper.selectDictTypeByType(dictType);
}
/**
* 批量删除字典类型
*
* @param ids 需要删除的数据
* @return 结果
*/
@Override
public int deleteDictTypeByIds(String ids)
{
Long[] dictIds = Convert.toLongArray(ids);
for (Long dictId : dictIds)
{
SysDictType dictType = selectDictTypeById(dictId);
if (dictDataMapper.countDictDataByType(dictType.getDictType()) > 0)
{
throw new BusinessException(String.format("%1$s已分配,不能删除", dictType.getDictName()));
}
}
int count = dictTypeMapper.deleteDictTypeByIds(dictIds);
if (count > 0)
{
DictUtils.clearDictCache();
}
return count;
}
/**
* 清空缓存数据
*/
@Override
public void clearCache()
{
DictUtils.clearDictCache();
}
/**
* 新增保存字典类型信息
*
* @param dictType 字典类型信息
* @return 结果
*/
@Override
public int insertDictType(SysDictType dictType)
{
int row = dictTypeMapper.insertDictType(dictType);
if (row > 0)
{
DictUtils.clearDictCache();
}
return row;
}
/**
* 修改保存字典类型信息
*
* @param dictType 字典类型信息
* @return 结果
*/
@Override
@Transactional
public int updateDictType(SysDictType dictType)
{
SysDictType oldDict = dictTypeMapper.selectDictTypeById(dictType.getDictId());
dictDataMapper.updateDictDataType(oldDict.getDictType(), dictType.getDictType());
int row = dictTypeMapper.updateDictType(dictType);
if (row > 0)
{
DictUtils.clearDictCache();
}
return row;
}
/**
* 校验字典类型称是否唯一
*
* @param dict 字典类型
* @return 结果
*/
@Override
public String checkDictTypeUnique(SysDictType dict)
{
Long dictId = StringUtils.isNull(dict.getDictId()) ? -1L : dict.getDictId();
SysDictType dictType = dictTypeMapper.checkDictTypeUnique(dict.getDictType());
if (StringUtils.isNotNull(dictType) && dictType.getDictId().longValue() != dictId.longValue())
{
return UserConstants.DICT_TYPE_NOT_UNIQUE;
}
return UserConstants.DICT_TYPE_UNIQUE;
}
/**
* 查询字典类型树
*
* @param dictType 字典类型
* @return 所有字典类型
*/
@Override
public List<Ztree> selectDictTree(SysDictType dictType)
{
List<Ztree> ztrees = new ArrayList<Ztree>();
List<SysDictType> dictList = dictTypeMapper.selectDictTypeList(dictType);
for (SysDictType dict : dictList)
{
if (UserConstants.DICT_NORMAL.equals(dict.getStatus()))
{
Ztree ztree = new Ztree();
ztree.setId(dict.getDictId());
ztree.setName(transDictName(dict));
ztree.setTitle(dict.getDictType());
ztrees.add(ztree);
}
}
return ztrees;
}
public String transDictName(SysDictType dictType)
{
StringBuffer sb = new StringBuffer();
sb.append("(" + dictType.getDictName() + ")");
sb.append(" " + dictType.getDictType());
return sb.toString();
}
}
package com.ruoyi.system.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.utils.DictUtils;
import com.ruoyi.system.mapper.SysDictDataMapper;
import com.ruoyi.system.service.ISysDictDataService;
/**
* 字典 业务层处理
*
* @author ruoyi
*/
@Service
public class SysDictDataServiceImpl implements ISysDictDataService
{
@Autowired
private SysDictDataMapper dictDataMapper;
/**
* 根据条件分页查询字典数据
*
* @param dictData 字典数据信息
* @return 字典数据集合信息
*/
@Override
public List<SysDictData> selectDictDataList(SysDictData dictData)
{
return dictDataMapper.selectDictDataList(dictData);
}
/**
* 根据字典类型和字典键值查询字典数据信息
*
* @param dictType 字典类型
* @param dictValue 字典键值
* @return 字典标签
*/
@Override
public String selectDictLabel(String dictType, String dictValue)
{
return dictDataMapper.selectDictLabel(dictType, dictValue);
}
/**
* 根据字典数据ID查询信息
*
* @param dictCode 字典数据ID
* @return 字典数据
*/
@Override
public SysDictData selectDictDataById(Long dictCode)
{
return dictDataMapper.selectDictDataById(dictCode);
}
/**
* 批量删除字典数据
*
* @param ids 需要删除的数据
* @return 结果
*/
@Override
public int deleteDictDataByIds(String ids)
{
int row = dictDataMapper.deleteDictDataByIds(Convert.toStrArray(ids));
if (row > 0)
{
DictUtils.clearDictCache();
}
return row;
}
/**
* 新增保存字典数据信息
*
* @param dictData 字典数据信息
* @return 结果
*/
@Override
public int insertDictData(SysDictData dictData)
{
int row = dictDataMapper.insertDictData(dictData);
if (row > 0)
{
DictUtils.clearDictCache();
}
return row;
}
/**
* 修改保存字典数据信息
*
* @param dictData 字典数据信息
* @return 结果
*/
@Override
public int updateDictData(SysDictData dictData)
{
int row = dictDataMapper.updateDictData(dictData);
if (row > 0)
{
DictUtils.clearDictCache();
}
return row;
}
}
package com.ruoyi.framework.web.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.system.service.ISysDictDataService;
import com.ruoyi.system.service.ISysDictTypeService;
/**
* RuoYi首创 html调用 thymeleaf 实现字典读取
*
* @author ruoyi
*/
@Service("dict")
public class DictService
{
@Autowired
private ISysDictTypeService dictTypeService;
@Autowired
private ISysDictDataService dictDataService;
/**
* 根据字典类型查询字典数据信息
*
* @param dictType 字典类型
* @return 参数键值
*/
public List<SysDictData> getType(String dictType)
{
return dictTypeService.selectDictDataByType(dictType);
}
/**
* 根据字典类型和字典键值查询字典数据信息
*
* @param dictType 字典类型
* @param dictValue 字典键值
* @return 字典标签
*/
public String getLabel(String dictType, String dictValue)
{
return dictDataService.selectDictLabel(dictType, dictValue);
}
}
其本质是使用的SpringEL语法调用了spring的上下文的beans取具体的bean对象获取到字典相关对象,然后根据字典类型找对应的字典键值。很巧妙!!这个可能蛮多人都不知道这个特性,这个整合spring
上面的项目除了字典回显之外还有的就是选中单选框,使用的是th:checked属性,很强大,具体的值还是走的上面的解析,获取上下文对象,然后按类型找,拿到它的值以及名字。用一个案例讲是因为其往往是字典和单选伴随的出现,当然如果仅仅是只要获取值回显,实际上就是th:checked=单选框的数值。
我们的默认是正常,选个停用的测试一下:
严谨一点再用正常的修改看看会不会跑到停用:
为什么要再看正常呢?因为使用th:selected的时候如果没有和name的参数比较的话,会出现获取字典类型对应的数据的最后一个的情况,我想check也一样所以试一下确实这样,所以还是要细心不然写的都是bug!!
使用th:switch,th:case
后端一样,查对象然后放入域对象
/**
* 查看工作日志详情
* @param worklogId
* @return
*/
@RequiresPermissions("worklog:worklog:detail")
@GetMapping("/detail/{worklogId}")
public String detail(@PathVariable("worklogId") Long worklogId,ModelMap mmap){
MtWorklog mtWorklog = mtWorklogService.selectMtWorklogById(worklogId);
mmap.put("worklog",mtWorklog);
return prefix+"/detail";
}
前端
<div th:object="${worklog}">
<div th:switch="*{taskType}">
<label>任务类型:</label>
<span th:case="1">需求</span>
<!--使用模板引擎填充文本的写法-->
<span th:case="2" th:text="BUG"></span>
<span th:case="3">其他</span>
</div>
值得注意的是:如果不是使用获取bean对象的话,后端在控制层一个要把集合或者是对象传入模型中,使用mv,model,modelmap都可以。前端用th:object获取对象即可,之后的值使用${}或者*{}取即可。