feat: 后台会员反馈管理

This commit is contained in:
xiongxiaoyang 2023-04-18 11:23:45 +08:00
parent aa2929a3cd
commit e44978617f
16 changed files with 1095 additions and 2 deletions

View File

@ -41,4 +41,11 @@ VALUES (1, 323);
INSERT INTO sys_role_menu (role_id, menu_id)
VALUES (1, 324);
INSERT INTO sys_role_menu (role_id, menu_id)
VALUES (1, 325);
VALUES (1, 325);
INSERT INTO `sys_menu` (`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
VALUES (410, '400', '会员反馈', 'novel/userFeedback', 'novel:userFeedback:userFeedback', '1', 'fa', '16');
INSERT INTO sys_role_menu (role_id, menu_id)
VALUES (1, 410);

View File

@ -2993,4 +2993,10 @@ VALUES (1, 323);
INSERT INTO sys_role_menu (role_id, menu_id)
VALUES (1, 324);
INSERT INTO sys_role_menu (role_id, menu_id)
VALUES (1, 325);
VALUES (1, 325);
INSERT INTO `sys_menu` (`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
VALUES (410, '400', '会员反馈', 'novel/userFeedback', 'novel:userFeedback:userFeedback', '1', 'fa', '16');
INSERT INTO sys_role_menu (role_id, menu_id)
VALUES (1, 410);

View File

@ -0,0 +1,135 @@
package com.java2nb.novel.controller;
import java.util.List;
import java.util.Map;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import io.swagger.annotations.ApiOperation;
import com.java2nb.novel.domain.UserFeedbackDO;
import com.java2nb.novel.service.UserFeedbackService;
import com.java2nb.common.utils.PageBean;
import com.java2nb.common.utils.Query;
import com.java2nb.common.utils.R;
/**
*
*
* @author xiongxy
* @email 1179705413@qq.com
* @date 2023-04-18 11:08:54
*/
@Controller
@RequestMapping("/novel/userFeedback")
public class UserFeedbackController {
@Autowired
private UserFeedbackService userFeedbackService;
@GetMapping()
@RequiresPermissions("novel:userFeedback:userFeedback")
String UserFeedback() {
return "novel/userFeedback/userFeedback";
}
@ApiOperation(value = "获取列表", notes = "获取列表")
@ResponseBody
@GetMapping("/list")
@RequiresPermissions("novel:userFeedback:userFeedback")
public R list(@RequestParam Map<String, Object> params) {
//查询列表数据
Query query = new Query(params);
List<UserFeedbackDO> userFeedbackList = userFeedbackService.list(query);
int total = userFeedbackService.count(query);
PageBean pageBean = new PageBean(userFeedbackList, total);
return R.ok().put("data", pageBean);
}
@ApiOperation(value = "新增页面", notes = "新增页面")
@GetMapping("/add")
@RequiresPermissions("novel:userFeedback:add")
String add() {
return "novel/userFeedback/add";
}
@ApiOperation(value = "修改页面", notes = "修改页面")
@GetMapping("/edit/{id}")
@RequiresPermissions("novel:userFeedback:edit")
String edit(@PathVariable("id") Long id, Model model) {
UserFeedbackDO userFeedback = userFeedbackService.get(id);
model.addAttribute("userFeedback", userFeedback);
return "novel/userFeedback/edit";
}
@ApiOperation(value = "查看页面", notes = "查看页面")
@GetMapping("/detail/{id}")
@RequiresPermissions("novel:userFeedback:detail")
String detail(@PathVariable("id") Long id, Model model) {
UserFeedbackDO userFeedback = userFeedbackService.get(id);
model.addAttribute("userFeedback", userFeedback);
return "novel/userFeedback/detail";
}
/**
* 保存
*/
@ApiOperation(value = "新增", notes = "新增")
@ResponseBody
@PostMapping("/save")
@RequiresPermissions("novel:userFeedback:add")
public R save( UserFeedbackDO userFeedback) {
if (userFeedbackService.save(userFeedback) > 0) {
return R.ok();
}
return R.error();
}
/**
* 修改
*/
@ApiOperation(value = "修改", notes = "修改")
@ResponseBody
@RequestMapping("/update")
@RequiresPermissions("novel:userFeedback:edit")
public R update( UserFeedbackDO userFeedback) {
userFeedbackService.update(userFeedback);
return R.ok();
}
/**
* 删除
*/
@ApiOperation(value = "删除", notes = "删除")
@PostMapping("/remove")
@ResponseBody
@RequiresPermissions("novel:userFeedback:remove")
public R remove( Long id) {
if (userFeedbackService.remove(id) > 0) {
return R.ok();
}
return R.error();
}
/**
* 删除
*/
@ApiOperation(value = "批量删除", notes = "批量删除")
@PostMapping("/batchRemove")
@ResponseBody
@RequiresPermissions("novel:userFeedback:batchRemove")
public R remove(@RequestParam("ids[]") Long[] ids) {
userFeedbackService.batchRemove(ids);
return R.ok();
}
}

View File

@ -0,0 +1,32 @@
package com.java2nb.novel.dao;
import com.java2nb.novel.domain.UserFeedbackDO;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.annotations.Mapper;
/**
*
* @author xiongxy
* @email 1179705413@qq.com
* @date 2023-04-18 11:08:54
*/
@Mapper
public interface UserFeedbackDao {
UserFeedbackDO get(Long id);
List<UserFeedbackDO> list(Map<String,Object> map);
int count(Map<String,Object> map);
int save(UserFeedbackDO userFeedback);
int update(UserFeedbackDO userFeedback);
int remove(Long id);
int batchRemove(Long[] ids);
}

View File

@ -0,0 +1,103 @@
package com.java2nb.novel.domain;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.java2nb.common.jsonserializer.LongToStringSerializer;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.util.Date;
/**
* @author xiongxy
* @email 1179705413@qq.com
* @date 2023-04-18 11:08:54
*/
public class UserFeedbackDO implements Serializable {
private static final long serialVersionUID = 1L;
//主键id
//java中的long能表示的范围比js中number大,也就意味着部分数值在js中存不下(变成不准确的值)
//所以通过序列化成字符串来解决
@JsonSerialize(using = LongToStringSerializer.class)
private Long id;
//用户id
//java中的long能表示的范围比js中number大,也就意味着部分数值在js中存不下(变成不准确的值)
//所以通过序列化成字符串来解决
@JsonSerialize(using = LongToStringSerializer.class)
private Long userId;
//反馈内容
private String content;
//反馈时间
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
private String userName;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
/**
* 设置主键id
*/
public void setId(Long id) {
this.id = id;
}
/**
* 获取主键id
*/
public Long getId() {
return id;
}
/**
* 设置用户id
*/
public void setUserId(Long userId) {
this.userId = userId;
}
/**
* 获取用户id
*/
public Long getUserId() {
return userId;
}
/**
* 设置反馈内容
*/
public void setContent(String content) {
this.content = content;
}
/**
* 获取反馈内容
*/
public String getContent() {
return content;
}
/**
* 设置反馈时间
*/
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
/**
* 获取反馈时间
*/
public Date getCreateTime() {
return createTime;
}
}

View File

@ -0,0 +1,30 @@
package com.java2nb.novel.service;
import com.java2nb.novel.domain.UserFeedbackDO;
import java.util.List;
import java.util.Map;
/**
*
*
* @author xiongxy
* @email 1179705413@qq.com
* @date 2023-04-18 11:08:54
*/
public interface UserFeedbackService {
UserFeedbackDO get(Long id);
List<UserFeedbackDO> list(Map<String, Object> map);
int count(Map<String, Object> map);
int save(UserFeedbackDO userFeedback);
int update(UserFeedbackDO userFeedback);
int remove(Long id);
int batchRemove(Long[] ids);
}

View File

@ -0,0 +1,67 @@
package com.java2nb.novel.service.impl;
import com.java2nb.novel.dao.UserDao;
import com.java2nb.novel.dao.UserFeedbackDao;
import com.java2nb.novel.domain.UserDO;
import com.java2nb.novel.domain.UserFeedbackDO;
import com.java2nb.novel.service.UserFeedbackService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Service
public class UserFeedbackServiceImpl implements UserFeedbackService {
@Autowired
private UserFeedbackDao userFeedbackDao;
@Autowired
private UserDao userDao;
@Override
public UserFeedbackDO get(Long id) {
return userFeedbackDao.get(id);
}
@Override
public List<UserFeedbackDO> list(Map<String, Object> map) {
List<UserFeedbackDO> list = userFeedbackDao.list(map);
if (!CollectionUtils.isEmpty(list)) {
List<Long> userIds = list.stream().map(UserFeedbackDO::getUserId).collect(Collectors.toList());
Map<Long, String> userNameMap = userDao.batchGet(userIds).stream()
.collect(Collectors.toMap(UserDO::getId, UserDO::getUsername));
list.forEach(v -> v.setUserName(userNameMap.get(v.getUserId())));
}
return list;
}
@Override
public int count(Map<String, Object> map) {
return userFeedbackDao.count(map);
}
@Override
public int save(UserFeedbackDO userFeedback) {
return userFeedbackDao.save(userFeedback);
}
@Override
public int update(UserFeedbackDO userFeedback) {
return userFeedbackDao.update(userFeedback);
}
@Override
public int remove(Long id) {
return userFeedbackDao.remove(id);
}
@Override
public int batchRemove(Long[] ids) {
return userFeedbackDao.batchRemove(ids);
}
}

View File

@ -0,0 +1,96 @@
<?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.java2nb.novel.dao.UserFeedbackDao">
<select id="get" resultType="com.java2nb.novel.domain.UserFeedbackDO">
select `id`,`user_id`,`content`,`create_time` from user_feedback where id = #{value}
</select>
<select id="list" resultType="com.java2nb.novel.domain.UserFeedbackDO">
select `id`,`user_id`,`content`,`create_time` from user_feedback
<where>
<if test="id != null and id != ''"> and id = #{id} </if>
<if test="userId != null and userId != ''"> and user_id = #{userId} </if>
<if test="content != null and content != ''"> and content = #{content} </if>
<if test="createTime != null and createTime != ''"> and create_time = #{createTime} </if>
</where>
<choose>
<when test="sort != null and sort.trim() != ''">
order by ${sort} ${order}
</when>
<otherwise>
order by id desc
</otherwise>
</choose>
<if test="offset != null and limit != null">
limit #{offset}, #{limit}
</if>
</select>
<select id="count" resultType="int">
select count(*) from user_feedback
<where>
<if test="id != null and id != ''"> and id = #{id} </if>
<if test="userId != null and userId != ''"> and user_id = #{userId} </if>
<if test="content != null and content != ''"> and content = #{content} </if>
<if test="createTime != null and createTime != ''"> and create_time = #{createTime} </if>
</where>
</select>
<insert id="save" parameterType="com.java2nb.novel.domain.UserFeedbackDO">
insert into user_feedback
(
`id`,
`user_id`,
`content`,
`create_time`
)
values
(
#{id},
#{userId},
#{content},
#{createTime}
)
</insert>
<insert id="saveSelective" parameterType="com.java2nb.novel.domain.UserFeedbackDO">
insert into user_feedback
(
<if test="id != null"> `id`, </if>
<if test="userId != null"> `user_id`, </if>
<if test="content != null"> `content`, </if>
<if test="createTime != null"> `create_time` </if>
)
values
(
<if test="id != null"> #{id}, </if>
<if test="userId != null"> #{userId}, </if>
<if test="content != null"> #{content}, </if>
<if test="createTime != null"> #{createTime} </if>
)
</insert>
<update id="update" parameterType="com.java2nb.novel.domain.UserFeedbackDO">
update user_feedback
<set>
<if test="userId != null">`user_id` = #{userId}, </if>
<if test="content != null">`content` = #{content}, </if>
<if test="createTime != null">`create_time` = #{createTime}</if>
</set>
where id = #{id}
</update>
<delete id="remove">
delete from user_feedback where id = #{value}
</delete>
<delete id="batchRemove">
delete from user_feedback where id in
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
</mapper>

View File

@ -0,0 +1,107 @@
var E = window.wangEditor;
$("[id^='contentEditor']").each(function (index, ele) {
var relName = $(ele).attr("id").substring(13);
var editor = new E('#contentEditor' + relName);
// 自定义菜单配置
editor.customConfig.menus = [
'head', // 标题
'bold', // 粗体
'fontSize', // 字号
'fontName', // 字体
'italic', // 斜体
'underline', // 下划线
'strikeThrough', // 删除线
'foreColor', // 文字颜色
//'backColor', // 背景颜色
//'link', // 插入链接
'list', // 列表
'justify', // 对齐方式
'quote', // 引用
'emoticon', // 表情
'image', // 插入图片
//'table', // 表格
//'video', // 插入视频
//'code', // 插入代码
'undo', // 撤销
'redo' // 重复
];
editor.customConfig.onchange = function (html) {
// html 即变化之后的内容
$("#" + relName).val(html);
}
editor.customConfig.uploadImgShowBase64 = true;
editor.create();
})
$("[id^='picImage']").each(function (index, ele) {
var relName = $(ele).attr("id").substring(8);
layui.use('upload', function () {
var upload = layui.upload;
//执行实例
var uploadInst = upload.render({
elem: '#picImage' + relName, //绑定元素
url: '/common/sysFile/upload', //上传接口
size: 1000,
accept: 'file',
done: function (r) {
$("#picImage" + relName).attr("src", r.fileName);
$("#" + relName).val(r.fileName);
},
error: function (r) {
layer.msg(r.msg);
}
});
});
});
$().ready(function () {
validateRule();
});
$.validator.setDefaults({
submitHandler: function () {
save();
}
});
function save() {
$.ajax({
cache: true,
type: "POST",
url: "/novel/userFeedback/save",
data: $('#signupForm').serialize(),// 你的formid
async: false,
error: function (request) {
parent.layer.alert("Connection error");
},
success: function (data) {
if (data.code == 0) {
parent.layer.msg("操作成功");
parent.reLoad();
var index = parent.layer.getFrameIndex(window.name); // 获取窗口索引
parent.layer.close(index);
} else {
parent.layer.alert(data.msg)
}
}
});
}
function validateRule() {
var icon = "<i class='fa fa-times-circle'></i> ";
$("#signupForm").validate({
ignore: "",
rules: {
},
messages: {
}
})
}

View File

@ -0,0 +1,103 @@
var E = window.wangEditor;
$("[id^='contentEditor']").each(function (index, ele) {
var relName = $(ele).attr("id").substring(13);
var editor = new E('#contentEditor' + relName);
// 自定义菜单配置
editor.customConfig.menus = [
'head', // 标题
'bold', // 粗体
'fontSize', // 字号
'fontName', // 字体
'italic', // 斜体
'underline', // 下划线
'strikeThrough', // 删除线
'foreColor', // 文字颜色
//'backColor', // 背景颜色
//'link', // 插入链接
'list', // 列表
'justify', // 对齐方式
'quote', // 引用
'emoticon', // 表情
'image', // 插入图片
//'table', // 表格
//'video', // 插入视频
//'code', // 插入代码
'undo', // 撤销
'redo' // 重复
];
editor.customConfig.onchange = function (html) {
// html 即变化之后的内容
$("#" + relName).val(html);
}
editor.customConfig.uploadImgShowBase64 = true;
editor.create();
editor.txt.html($("#" + relName).val());
})
$("[id^='picImage']").each(function (index, ele) {
var relName = $(ele).attr("id").substring(8);
layui.use('upload', function () {
var upload = layui.upload;
//执行实例
var uploadInst = upload.render({
elem: '#picImage' + relName, //绑定元素
url: '/common/sysFile/upload', //上传接口
size: 1000,
accept: 'file',
done: function (r) {
$("#picImage" + relName).attr("src", r.fileName);
$("#" + relName).val(r.fileName);
},
error: function (r) {
layer.msg(r.msg);
}
});
});
});
$().ready(function () {
validateRule();
});
$.validator.setDefaults({
submitHandler: function () {
update();
}
});
function update() {
$.ajax({
cache: true,
type: "POST",
url: "/novel/userFeedback/update",
data: $('#signupForm').serialize(),// 你的formid
async: false,
error: function (request) {
parent.layer.alert("Connection error");
},
success: function (data) {
if (data.code == 0) {
parent.layer.msg("操作成功");
parent.reLoad();
var index = parent.layer.getFrameIndex(window.name); // 获取窗口索引
parent.layer.close(index);
} else {
parent.layer.alert(data.msg)
}
}
});
}
function validateRule() {
var icon = "<i class='fa fa-times-circle'></i> ";
$("#signupForm").validate({
ignore: "",
rules: {
},
messages: {
}
})
}

View File

@ -0,0 +1,177 @@
var prefix = "/novel/userFeedback"
$(function () {
load();
});
function load() {
$('#exampleTable')
.bootstrapTable(
{
method: 'get', // 服务器数据的请求方式 get or post
url: prefix + "/list", // 服务器数据的加载地址
// showRefresh : true,
// showToggle : true,
// showColumns : true,
iconSize: 'outline',
toolbar: '#exampleToolbar',
striped: true, // 设置为true会有隔行变色效果
dataType: "json", // 服务器返回的数据类型
pagination: true, // 设置为true会在底部显示分页条
// queryParamsType : "limit",
// //设置为limit则会发送符合RESTFull格式的参数
singleSelect: false, // 设置为true将禁止多选
// contentType : "application/x-www-form-urlencoded",
// //发送到服务器的数据编码类型
pageSize: 10, // 如果设置了分页每页数据条数
pageNumber: 1, // 如果设置了分布首页页码
//search : true, // 是否显示搜索框
showColumns: false, // 是否显示内容下拉框选择显示的列
sidePagination: "server", // 设置在哪里进行分页可选值为"client" 或者 "server"
queryParams: function (params) {
//说明传入后台的参数包括offset开始索引limit步长sort排序列orderdesc或者,以及所有列的键值对
var queryParams = getFormJson("searchForm");
queryParams.limit = params.limit;
queryParams.offset = params.offset;
return queryParams;
},
// //请求服务器数据时你可以通过重写参数的方式添加一些额外的参数例如 toolbar 中的参数 如果
// queryParamsType = 'limit' ,返回参数必须包含
// limit, offset, search, sort, order 否则, 需要包含:
// pageSize, pageNumber, searchText, sortName,
// sortOrder.
// 返回false将会终止请求
responseHandler: function (rs) {
if (rs.code == 0) {
return rs.data;
} else {
parent.layer.alert(rs.msg)
return {total: 0, rows: []};
}
},
columns: [
{
title: '序号',
formatter: function () {
return arguments[2] + 1;
}
},
{
field: 'userName',
title: '反馈用户'
},
{
field: 'content',
title: '反馈内容'
},
{
field: 'createTime',
title: '反馈时间'
}
]
});
}
function reLoad() {
$('#exampleTable').bootstrapTable('refresh');
}
function add() {
layer.open({
type: 2,
title: '增加',
maxmin: true,
shadeClose: false, // 点击遮罩关闭层
area: ['800px', '520px'],
content: prefix + '/add' // iframe的url
});
}
function detail(id) {
layer.open({
type: 2,
title: '详情',
maxmin: true,
shadeClose: false, // 点击遮罩关闭层
area: ['800px', '520px'],
content: prefix + '/detail/' + id // iframe的url
});
}
function edit(id) {
layer.open({
type: 2,
title: '编辑',
maxmin: true,
shadeClose: false, // 点击遮罩关闭层
area: ['800px', '520px'],
content: prefix + '/edit/' + id // iframe的url
});
}
function remove(id) {
layer.confirm('确定要删除选中的记录', {
btn: ['确定', '取消']
}, function () {
$.ajax({
url: prefix + "/remove",
type: "post",
data: {
'id': id
},
success: function (r) {
if (r.code == 0) {
layer.msg(r.msg);
reLoad();
} else {
layer.msg(r.msg);
}
}
});
})
}
function resetPwd(id) {
}
function batchRemove() {
var rows = $('#exampleTable').bootstrapTable('getSelections'); // 返回所有选择的行当没有选择的记录时返回一个空数组
if (rows.length == 0) {
layer.msg("请选择要删除的数据");
return;
}
layer.confirm("确认要删除选中的'" + rows.length + "'条数据吗?", {
btn: ['确定', '取消']
// 按钮
}, function () {
var ids = new Array();
// 遍历所有选择的行数据取每条数据对应的ID
$.each(rows, function (i, row) {
ids[i] = row['id'];
});
$.ajax({
type: 'POST',
data: {
"ids": ids
},
url: prefix + '/batchRemove',
success: function (r) {
if (r.code == 0) {
layer.msg(r.msg);
reLoad();
} else {
layer.msg(r.msg);
}
}
});
}, function () {
});
}

View File

@ -0,0 +1,18 @@
-- 菜单SQL
INSERT INTO `sys_menu` (`parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
VALUES ('1', '', 'novel/userFeedback', 'novel:userFeedback:userFeedback', '1', 'fa', '6');
-- 按钮父菜单ID
set @parentId = @@identity;
-- 菜单对应按钮SQL
INSERT INTO `sys_menu` (`parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
SELECT @parentId, '查看', null, 'novel:userFeedback:detail', '2', null, '6';
INSERT INTO `sys_menu` (`parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
SELECT @parentId, '新增', null, 'novel:userFeedback:add', '2', null, '6';
INSERT INTO `sys_menu` (`parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
SELECT @parentId, '修改', null, 'novel:userFeedback:edit', '2', null, '6';
INSERT INTO `sys_menu` (`parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
SELECT @parentId, '删除', null, 'novel:userFeedback:remove', '2', null, '6';
INSERT INTO `sys_menu` (`parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`)
SELECT @parentId, '批量删除', null, 'novel:userFeedback:batchRemove', '2', null, '6';

View File

@ -0,0 +1,57 @@
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<head th:include="include :: header"></head>
<body class="gray-bg">
<div class="wrapper wrapper-content ">
<div class="row">
<div class="col-sm-12">
<div class="ibox float-e-margins">
<div class="ibox-content">
<form class="form-horizontal m-t" id="signupForm">
<div class="form-group">
<label class="col-sm-3 control-label">用户id</label>
<div class="col-sm-8">
<input id="userId" name="userId"
class="form-control"
type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">反馈内容:</label>
<div class="col-sm-8">
<input id="content" name="content"
class="form-control"
type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">反馈时间:</label>
<div class="col-sm-8">
<input type="text" class="laydate-icon layer-date form-control"
id="createTime"
name="createTime"
onclick="laydate({istime: true, format: 'YYYY-MM-DD hh:mm:ss'})"
style="background-color: #fff;" readonly="readonly"/>
</div>
</div>
<div class="form-group">
<div class="col-sm-8 col-sm-offset-3">
<button type="submit" class="btn btn-primary">提交</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<div th:include="include::footer"></div>
<script type="text/javascript" src="/wangEditor/release/wangEditor.js"></script>
<script type="text/javascript" src="/js/appjs/novel/userFeedback/add.js">
</script>
</body>
</html>

View File

@ -0,0 +1,51 @@
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<head th:include="include :: header"></head>
<body class="gray-bg">
<div class="wrapper wrapper-content ">
<div class="row">
<div class="col-sm-12">
<div class="ibox float-e-margins">
<div class="ibox-content">
<form class="form-horizontal m-t" id="signupForm">
<input id="id" name="id" th:value="${userFeedback.id}"
type="hidden">
<div class="form-group">
<label class="col-sm-3 control-label">用户id</label>
<div style="padding-top:8px" class="col-sm-8"
th:text="${userFeedback.userId}">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">反馈内容:</label>
<div style="padding-top:8px" class="col-sm-8"
th:text="${userFeedback.content}">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">反馈时间:</label>
<div style="padding-top:8px" class="col-sm-8"
th:text="${userFeedback.createTime}==null?null:${#dates.format(userFeedback.createTime,'yyyy-MM-dd HH:mm:ss')}">
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<div th:include="include::footer"></div>
</body>
</html>

View File

@ -0,0 +1,59 @@
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<head th:include="include :: header"></head>
<body class="gray-bg">
<div class="wrapper wrapper-content ">
<div class="row">
<div class="col-sm-12">
<div class="ibox float-e-margins">
<div class="ibox-content">
<form class="form-horizontal m-t" id="signupForm">
<input id="id" name="id" th:value="${userFeedback.id}"
type="hidden">
<div class="form-group">
<label class="col-sm-3 control-label">用户id</label>
<div class="col-sm-8">
<input id="userId" name="userId"
th:value="${userFeedback.userId}"
class="form-control"
type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">反馈内容:</label>
<div class="col-sm-8">
<input id="content" name="content"
th:value="${userFeedback.content}"
class="form-control"
type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">反馈时间:</label>
<div class="col-sm-8">
<input type="text" class="laydate-icon layer-date form-control"
id="createTime"
name="createTime"
th:value="${userFeedback.createTime}==null?null:${#dates.format(userFeedback.createTime,'yyyy-MM-dd HH:mm:ss')}"
onclick="laydate({istime: true, format: 'YYYY-MM-DD hh:mm:ss'})"
style="background-color: #fff;" readonly="readonly"/>
</div>
</div>
<div class="form-group">
<div class="col-sm-8 col-sm-offset-3">
<button type="submit" class="btn btn-primary">提交</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<div th:include="include::footer"></div>
<script type="text/javascript" src="/wangEditor/release/wangEditor.js"></script>
<script type="text/javascript" src="/js/appjs/novel/userFeedback/edit.js">
</script>
</body>
</html>

View File

@ -0,0 +1,45 @@
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<head th:include="include :: header"></head>
<body class="gray-bg">
<div class="wrapper wrapper-content ">
<div class="col-sm-12">
<div class="ibox">
<div class="ibox-body">
<div class="fixed-table-toolbar">
</div>
<table id="exampleTable" data-mobile-responsive="true">
</table>
</div>
</div>
</div>
</div>
<!--shiro控制bootstraptable行内按钮看见性 -->
<div>
<script type="text/javascript">
var s_detail_h = 'hidden';
var s_edit_h = 'hidden';
var s_remove_h = 'hidden';
</script>
</div>
<div shiro:hasPermission="test:order:detail">
<script type="text/javascript">
s_detail_h = '';
</script>
</div>
<div shiro:hasPermission="novel:userFeedback:edit">
<script type="text/javascript">
s_edit_h = '';
</script>
</div>
<div shiro:hasPermission="novel:userFeedback:remove">
<script type="text/javascript">
var s_remove_h = '';
</script>
</div>
<div th:include="include :: footer"></div>
<script type="text/javascript" src="/js/appjs/novel/userFeedback/userFeedback.js"></script>
</body>
</html>