@学习步骤
若依框架搭建
通过git在其官网下载,idea可导入
在工程项目内有环境搭建手册按照上面的手册修改.yml文件,其次在sql文件夹下存在.sql文件,按照文件创建数据库,将数据库以及端扣绑定在刚刚修改的.yml文件。
创建自己的功能模块
后端搭建
添加标签功能,在此路径sysytem里创建自己的模块packet,并在packet里创建四个子packet分别为controller、domain、mapper、service,并创建java程序。
五个程序的代码
controller的代码
// An highlighted block
package com.ruoyi.project.system.text.controller;
import java.util.List;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.framework.web.page.TableDataInfo;
import com.ruoyi.project.system.text.domain.Text;
import com.ruoyi.project.system.text.service.ITextService;
/**
* 标签 信息处理操作
*/
@Controller
@RequestMapping("/system/text")
public class TextController extends BaseController
{
private String prefix="system/text";
@Autowired
private ITextService textService;
@RequiresPermissions("system:text:view")
@GetMapping()
public String text() {return prefix+"/text";}
/**
* 查询标签列表
*/
@RequiresPermissions("system:text:list")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(Text text)
{
startPage();
List<Text> list=textService.selectTextList(text);
return getDataTable(list);
}
/**
* 新增标签
*/
@GetMapping("/add")
public String add(){ return prefix+ "/add"; }
/**
* 新增保存标签
*
*/
@RequiresPermissions("system:text:add")
@Log(title = "便签", businessType = BusinessType.INSERT)
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave( Text text)
{
return toAjax(textService.insertText(text));
}
/**
* 修改公告
*/
@GetMapping("/edit/{textId}")
public String edit(@PathVariable("textId") Long textId, ModelMap mmap)
{
mmap.put("text", textService.selectTextById(textId));
return prefix + "/edit";
}
/**
* 修改保存公告
*/
@RequiresPermissions("system:text:edit")
@Log(title = "通知公告", businessType = BusinessType.UPDATE)
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(Text text)
{
return toAjax(textService.updateText(text));
}
/**
* 删除标签
*/
@RequiresPermissions("system:text:remove")
@Log(title = "便签", businessType = BusinessType.DELETE)
@PostMapping("/remove")
@ResponseBody
public AjaxResult remove(String ids)
{
return toAjax(textService.deleteTextByIds(ids));
}
}
Text程序代码
// An highlighted block
package com.ruoyi.project.system.text.domain;
import com.ruoyi.framework.web.domain.BaseEntity;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
public class Text extends BaseEntity {
private static final long serialVersionUID=1L;
//便签Id
private Long textId;
//标签
private String textTitle;
//标签类型
private String textType;
//标签内容
private String textContent;
//标签状态存活
private String status;
public Long getTextId(){return textId;}
public void setTextId(long textId){this.textId=textId;}
public void setTextTitle(String textTitle){this.textTitle=textTitle;}
@NotBlank(message = "标签标题不能为空")
@Size(min=0,max=50,message = "不能超过50个字")
public String getTextTitle(){return textTitle;}
public void setTextType(String textType){this.textType=textType;}
public String getTextType(){return textType;}
public void setTextContent(String textContent){this.textContent =textContent;}
public String getTextContent(){return textContent;}
public void setStatus(String status){this.status=status;}
public String getStatus(){return status;}
@Override
public String toString(){
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
.append("textId", getTextId())
.append("textTitle", getTextTitle())
.append("textType", getTextType())
.append("textContent", getTextContent())
.append("status", getStatus())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("remark", getRemark())
.toString();
}
}
TextMapper代码
package com.ruoyi.project.system.text.mapper;
import com.ruoyi.project.system.text.domain.Text;
import java.util.List;
public interface TextMapper {
/**
* 查询公告信息
*
* @param textId
* @return 公告信息
*/
public Text selectTextById(Long textId);
/**
* 查询公告列表
*
* @param text 公告信息
* @return 公告集合
*/
public List<Text> selectTextList(Text text);
/**
* 新增公告
*
* @param text 公告信息
* @return 结果
*/
public int insertText(Text text);
/**
* 修改公告
*
* @param text 公告信息
* @return 结果
*/
public int updateText(Text text);
/**
* 批量删除公告
*
* @param textIds 需要删除的数据Id
* @return 结果
*/
public int deleteTextByIds(String[] textIds);
}
ITextService的代码
// An highlighted block
package com.ruoyi.project.system.text.service;
import com.ruoyi.project.system.text.domain.Text;
import java.util.List;
/**
* 便签 服务层
*/
public interface ITextService {
/**
* 查询标签信息
* @param textId
* @return 标签信息
*
*/
public Text selectTextById(Long textId);
/**
* 查询标签列表
* @param text
* @reutn 标签集合
*/
public List<Text> selectTextList(Text text);
/**
* 新增标签
* @param text 公告信息
* @reurn 结果
*/
public int insertText(Text text);
/**
*修改广告
* @param text
* @return 结果
*/
public int updateText(Text text);
/**
* 删除广告
* @param ids
* @return 结果
*/
public int deleteTextByIds(String ids);
}
TextServicelmpl的代码
// An highlighted block
package com.ruoyi.project.system.text.service;
import com.ruoyi.project.system.notice.service.INoticeService;
import com.ruoyi.project.system.text.mapper.TextMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.project.system.text.mapper.TextMapper;
import com.ruoyi.project.system.text.domain.Text;
import com.ruoyi.common.utils.text.Convert;
import com.ruoyi.common.utils.security.ShiroUtils;
import java.util.List;
@Service
public class TextServicelmpl implements ITextService
{
@Autowired
private TextMapper textMapper;
/**
* 查询公告信息
*
* @param textId 标签Id
* @return 标签信息
*/
@Override
public Text selectTextById(Long textId)
{
return textMapper.selectTextById(textId);
}
/**
* 查询公告列表
*
* @param text 公告信息
* @return 公告集合
*/
@Override
public List<Text> selectTextList(Text text)
{
return textMapper.selectTextList(text);
}
/**
* 新增公告
*
* @param text 公告信息
* @return 结果
*/
@Override
public int insertText(Text text)
{
text.setCreateBy(ShiroUtils.getLoginName());
return textMapper.insertText(text);
}
/**
* 修改公告
*
* @param text 公告信息
* @return 结果
*/
@Override
public int updateText(Text text)
{
text.setUpdateBy(ShiroUtils.getLoginName());
return textMapper.updateText(text);
}
/**
* 删除公告对象
*
* @param ids 需要删除的数据Id
* @return 结果
*/
@Override
public int deleteTextByIds(String ids)
{
return textMapper.deleteTextByIds(Convert.toStrArray(ids));
}
}
编写TextMapping.xml文件 将后端与数据库进行连接的映射。
下面展示一些 内联代码片
。
// A code block
var foo = 'bar';
// An highlighted block
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.project.system.text.mapper.TextMapper">
<resultMap type="Text" id="TextResult">
<result property="textId" column="text_id" />
<result property="textTitle" column="text_title" />
<result property="textType" column="text_type" />
<result property="textContent" column="text_content" />
<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" />
<result property="remark" column="remark" />
</resultMap>
<sql id="selectTextVo">
select text_id, text_title, text_type, text_content, status, create_by, create_time, update_by, update_time, remark
from sys_text
</sql>
<select id="selectTextById" parameterType="Long" resultMap="TextResult">
<include refid="selectTextVo"/>
where text_id = #{textId}
</select>
<select id="selectTextList" parameterType="Text" resultMap="TextResult">
<include refid="selectTextVo"/>
<where>
<if test="textTitle != null and textTitle != ''">
AND text_title like concat('%', #{textTitle}, '%')
</if>
<if test="textType != null and textType != ''">
AND text_type = #{textType}
</if>
<if test="createBy != null and createBy != ''">
AND create_by like concat('%', #{createBy}, '%')
</if>
</where>
</select>
<insert id="insertText" parameterType="Text">
insert into sys_text (
<if test="textTitle != null and textTitle != '' ">text_title, </if>
<if test="textType != null and textType != '' ">text_type, </if>
<if test="textContent != null and textContent != '' ">text_content, </if>
<if test="status != null and status != '' ">status, </if>
<if test="remark != null and remark != ''">remark,</if>
<if test="createBy != null and createBy != ''">create_by,</if>
create_time
)values(
<if test="textTitle != null and textTitle != ''">#{textTitle}, </if>
<if test="textType != null and textType != ''">#{textType}, </if>
<if test="textContent != null and textContent != ''">#{textContent}, </if>
<if test="status != null and status != ''">#{status}, </if>
<if test="remark != null and remark != ''">#{remark},</if>
<if test="createBy != null and createBy != ''">#{createBy},</if>
sysdate()
)
</insert>
<update id="updateText" parameterType="Text">
update sys_text
<set>
<if test="textTitle != null and textTitle != ''">text_title = #{textTitle}, </if>
<if test="textType != null and textType != ''">text_type = #{textType}, </if>
<if test="textContent != null">text_content = #{textContent}, </if>
<if test="status != null and status != ''">status = #{status}, </if>
<if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
update_time = sysdate()
</set>
where text_id = #{textId}
</update>
<delete id="deleteTextByIds" parameterType="String">
delete from sys_text where text_id in
<foreach item="textId" collection="array" open="(" separator="," close=")">
#{textId}
</foreach>
</delete>
</mapper>
对数据库进行添加
创建自己模块的数据库 sys_text并添加元素
对与sys_menue进行添加为一级菜单
和相对于增删查改的四个二级菜单
还需要对sys_dict_type、sys_dict_data数据库进行添加。
编写前端
add.html文件
// An highlighted block
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
<head>
<th:block th:include="include :: header('新增标签公告')" />
<th:block th:include="include :: summernote-css" />
</head>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="form-text-add">
<div class="form-group">
<label class="col-sm-2 control-label is-required">公告标题:</label>
<div class="col-sm-10">
<input id="textTitle" name="textTitle" class="form-control" type="text" required>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">公告类型:</label>
<div class="col-sm-10">
<select name="textType" class="form-control m-b" th:with="type=${@dict.getType('sys_text_type')}">
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}"></option>
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">公告内容:</label>
<div class="col-sm-10">
<input id="textContent" name="textContent" type="hidden">
<div class="summernote"></div>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">公告状态:</label>
<div class="col-sm-10">
<div class="radio-box" th:each="dict : ${@dict.getType('sys_text_status')}">
<input type="radio" th:id="${dict.dictCode}" name="status" th:value="${dict.dictValue}" th:checked="${dict.default}">
<label th:for="${dict.dictCode}" th:text="${dict.dictLabel}"></label>
</div>
</div>
</div>
</form>
</div>
<th:block th:include="include :: footer" />
<th:block th:include="include :: summernote-js" />
<script type="text/javascript">
var prefix = ctx + "system/text";
$('.summernote').summernote({
placeholder: '请输入公告内容',
height : 192,
lang : 'zh-CN',
followingToolbar: false,
callbacks: {
onImageUpload: function (files) {
sendFile(files[0], this);
}
}
});
// 上传文件
function sendFile(file, obj) {
var data = new FormData();
data.append("file", file);
$.ajax({
type: "POST",
url: ctx + "common/upload",
data: data,
cache: false,
contentType: false,
processData: false,
dataType: 'json',
success: function(result) {
if (result.code == web_status.SUCCESS) {
$(obj).summernote('editor.insertImage', result.url, result.fileName);
} else {
$.modal.alertError(result.msg);
}
},
error: function(error) {
$.modal.alertWarning("图片上传失败。");
}
});
}
$("#form-text-add").validate({
focusCleanup: true
});
function submitHandler() {
if ($.validate.form()) {
var sHTML = $('.summernote').summernote('code');
$("#textContent").val(sHTML);
$.operate.save(prefix + "/add", $('#form-text-add').serialize());
}
}
</script>
</body>
</html>
edit.html文件
// An highlighted block
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
<head>
<th:block th:include="include :: header('修改通知公告')" />
<th:block th:include="include :: summernote-css" />
</head>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="form-text-edit" th:object="${text}">
<input id="textId" name="textId" th:field="*{textId}" type="hidden">
<div class="form-group">
<label class="col-sm-2 control-label is-required">公告标题:</label>
<div class="col-sm-10">
<input id="textTitle" name="textTitle" th:field="*{textTitle}" class="form-control" type="text" required>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">公告类型:</label>
<div class="col-sm-10">
<select name="textType" class="form-control m-b" th:with="type=${@dict.getType('sys_text_type')}">
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}" th:field="*{textType}"></option>
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">公告内容:</label>
<div class="col-sm-10">
<input id="textContent" name="textContent" th:field="*{textContent}" type="hidden">
<div id="editor" class="summernote"></div>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">公告状态:</label>
<div class="col-sm-10">
<div class="radio-box" th:each="dict : ${@dict.getType('sys_text_status')}">
<input type="radio" th:id="${dict.dictCode}" name="status" th:value="${dict.dictValue}" th:field="*{status}">
<label th:for="${dict.dictCode}" th:text="${dict.dictLabel}"></label>
</div>
</div>
</div>
</form>
</div>
<th:block th:include="include :: footer" />
<th:block th:include="include :: summernote-js" />
<script type="text/javascript">
var prefix = ctx + "system/text";
$(function() {
$('.summernote').summernote({
placeholder: '请输入公告内容',
height : 192,
lang : 'zh-CN',
followingToolbar: false,
callbacks: {
onImageUpload: function (files) {
sendFile(files[0], this);
}
}
});
var content = $("#textContent").val();
$('#editor').summernote('code', content);
});
// 上传文件
function sendFile(file, obj) {
var data = new FormData();
data.append("file", file);
$.ajax({
type: "POST",
url: ctx + "common/upload",
data: data,
cache: false,
contentType: false,
processData: false,
dataType: 'json',
success: function(result) {
if (result.code == web_status.SUCCESS) {
$(obj).summernote('editor.insertImage', result.url, result.fileName);
} else {
$.modal.alertError(result.msg);
}
},
error: function(error) {
$.modal.alertWarning("图片上传失败。");
}
});
}
$("#form-text-edit").validate({
focusCleanup: true
});
function submitHandler() {
if ($.validate.form()) {
var sHTML = $('.summernote').summernote('code');
$("#textContent").val(sHTML);
$.operate.save(prefix + "/edit", $('#form-text-edit').serialize());
}
}
</script>
</body>
</html>
text.htm文件编写
// An highlighted block
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<th:block th:include="include :: header('通知公告列表')" />
</head>
<body class="gray-bg">
<div class="container-div">
<div class="row">
<div class="col-sm-12 search-collapse">
<form id="text-form">
<div class="select-list">
<ul>
<li>
公告标题:<input type="text" name="textTitle"/>
</li>
<li>
操作人员:<input type="text" name="createBy"/>
</li>
<li>
公告类型:<select name="textType" th:with="type=${@dict.getType('sys_text_type')}">
<option value="">所有</option>
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}"></option>
</select>
</li>
<li>
<a class="btn btn-primary btn-rounded btn-sm" onclick="$.table.search()"><i class="fa fa-search"></i> 搜索</a>
<a class="btn btn-warning btn-rounded btn-sm" onclick="$.form.reset()"><i class="fa fa-refresh"></i> 重置</a>
</li>
</ul>
</div>
</form>
</div>
<div class="btn-group-sm" id="toolbar" role="group">
<a class="btn btn-success" onclick="$.operate.addFull()" shiro:hasPermission="system:text:add">
<i class="fa fa-plus"></i> 新增
</a>
<a class="btn btn-primary single disabled" onclick="$.operate.editFull()" shiro:hasPermission="system:text:edit">
<i class="fa fa-edit"></i> 修改
</a>
<a class="btn btn-danger multiple disabled" onclick="$.operate.remove()" shiro:hasPermission="system:text:remove">
<i class="fa fa-remove"></i> 删除
</a>
</div>
<div class="col-sm-12 select-table table-striped">
<table id="bootstrap-table"></table>
</div>
</div>
</div>
<th:block th:include="include :: footer" />
<script th:inline="javascript">
var editFlag = [[${@permission.hasPermi('system:text:edit')}]];
var removeFlag = [[${@permission.hasPermi('system:text:remove')}]];
var types = [[${@dict.getType('sys_text_type')}]];
var datas = [[${@dict.getType('sys_text_status')}]];
var prefix = ctx + "system/text";
$(function() {
var options = {
url: prefix + "/list",
createUrl: prefix + "/add",
updateUrl: prefix + "/edit/{id}",
removeUrl: prefix + "/remove",
modalName: "公告",
columns: [{
checkbox: true
},
{
field : 'textID',
title : '序号'
},
{
field : 'textTitle',
title : '公告标题'
},
{
field: 'textType',
title: '公告类型',
align: 'center',
formatter: function(value, row, index) {
return $.table.selectDictLabel(types, value);
}
},
{
field: 'status',
title: '状态',
align: 'center',
formatter: function(value, row, index) {
return $.table.selectDictLabel(datas, value);
}
},
{
field : 'createBy',
title : '创建者'
},
{
field: 'createTime',
title: '创建时间',
sortable: true
},
{
title: '操作',
align: 'center',
formatter: function(value, row, index) {
var actions = [];
actions.push('<a class="btn btn-success btn-xs ' + editFlag + '" href="javascript:void(0)" οnclick="$.operate.editFull(\'' + row.textId + '\')"><i class="fa fa-edit"></i>编辑</a> ');
actions.push('<a class="btn btn-danger btn-xs ' + removeFlag + '" href="javascript:void(0)" οnclick="$.operate.remove(\'' + row.textId + '\')"><i class="fa fa-remove"></i>删除</a>');
return actions.join('');
}
}]
};
$.table.init(options);
});
</script>
</body>
</html>
出现的问题
在进入自己创建的模块时候出现post请求不支持,但是可以进行添加操作,后台的数据库也确实增加,后来对报错进行断点检查。对输出的异常进断点,并往下逐步进行,由于传输的不止一个post文件并还有许多传输的get文件总能发现传输的函数,并在哪里打上断点,查看问题,最终发现传输的这个请求是get,而我原先的代码在此处的是postmapping(),导致不支持改为Gettingmap即可。由于controller存在多个传输方式 增删查改有采用post也有采用get的导致开始定义一个ReqquestMapping为父,下面在仔细的定义子mapping也不清楚到底是哪里出现问题,所以花了很长时间才解决问题。