Commit 8f75afed authored by Menethil's avatar Menethil
Browse files

Merge remote-tracking branch 'origin/master'

parents 854bacf6 ce225563
package org.linlinjava.litemall.admin.web;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.linlinjava.litemall.admin.annotation.LoginAdmin;
import org.linlinjava.litemall.core.util.RegexUtil;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.core.validator.Order;
import org.linlinjava.litemall.core.validator.Sort;
import org.linlinjava.litemall.db.domain.LitemallFeedback;
import org.linlinjava.litemall.db.service.LitemallFeedbackService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author Yogeek
* @date 2018/8/26 1:11
*/
@RestController
@RequestMapping("/admin/feedback")
@Validated
public class AdminFeedbackController {
private final Log logger = LogFactory.getLog(AdminFeedbackController.class);
@Autowired
private LitemallFeedbackService feedbackService;
@GetMapping("/list")
public Object list(@LoginAdmin Integer adminId,
Integer userId, String username,
@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10") Integer limit,
@Sort @RequestParam(defaultValue = "add_time") String sort,
@Order @RequestParam(defaultValue = "desc") String order) {
if(adminId == null){
return ResponseUtil.unlogin();
}
List<LitemallFeedback> feedbackList = feedbackService.querySelective(userId, username, page, limit, sort, order);
int total = feedbackService.countSelective(userId, username, page, limit, sort, order);
Map<String, Object> data = new HashMap<>();
data.put("total", total);
data.put("items", feedbackList);
return ResponseUtil.ok(data);
}
@PostMapping("/create")
public Object create(@LoginAdmin Integer adminId, @RequestBody LitemallFeedback feedback) {
if(adminId == null){
return ResponseUtil.unlogin();
}
String mobile = feedback.getMobile();
if(!RegexUtil.isMobileExact(mobile)){
return ResponseUtil.fail(403, "手机号格式不正确");
}
feedback.setAddTime(LocalDateTime.now());
feedbackService.add(feedback);
return ResponseUtil.ok(feedback);
}
@GetMapping("/read")
public Object read(@LoginAdmin Integer adminId, @NotNull Integer id){
if(adminId == null){
return ResponseUtil.unlogin();
}
if(id == null){
return ResponseUtil.badArgument();
}
LitemallFeedback feedback = feedbackService.findById(id);
return ResponseUtil.ok(feedback);
}
@PostMapping("/update")
public Object update(@LoginAdmin Integer adminId, @RequestBody LitemallFeedback feedback) {
if(adminId == null){
return ResponseUtil.unlogin();
}
feedbackService.updateById(feedback);
return ResponseUtil.ok(feedback);
}
@PostMapping("/delete")
public Object delete(@LoginAdmin Integer adminId, @RequestBody LitemallFeedback feedback){
if(adminId == null){
return ResponseUtil.unlogin();
}
feedbackService.delete(feedback.getId());
return ResponseUtil.ok();
}
}
......@@ -24,6 +24,7 @@ import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashMap;
......@@ -53,7 +54,8 @@ public class AdminOrderController {
@GetMapping("/list")
public Object list(@LoginAdmin Integer adminId,
Integer userId, String orderSn, @RequestParam(required = false, value = "orderStatusArray[]") List<Short> orderStatusArray,
Integer userId, String orderSn,
@RequestParam(required = false) List<Short> orderStatusArray,
@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10") Integer limit,
@Sort @RequestParam(defaultValue = "add_time") String sort,
......@@ -72,7 +74,7 @@ public class AdminOrderController {
}
@GetMapping("/detail")
public Object detail(@LoginAdmin Integer adminId, Integer id) {
public Object detail(@LoginAdmin Integer adminId, @NotNull Integer id) {
if (adminId == null) {
return ResponseUtil.unlogin();
}
......
......@@ -24,6 +24,7 @@
"mockjs": "1.0.1-beta3",
"normalize.css": "7.0.0",
"nprogress": "0.2.0",
"qs": "^6.5.2",
"screenfull": "3.3.2",
"v-charts": "^1.16.19",
"vue": "2.5.10",
......
import request from '@/utils/request'
export function listFeedback(query) {
return request({
url: '/feedback/list',
method: 'get',
params: query
})
}
export function createFeedback(data) {
return request({
url: '/feedback/create',
method: 'post',
data
})
}
export function readFeedback(data) {
return request({
url: '/feedback/read',
method: 'get',
data
})
}
export function updateFeedback(data) {
return request({
url: '/feedback/update',
method: 'post',
data
})
}
export function deleteFeedback(data) {
return request({
url: '/feedback/delete',
method: 'post',
data
})
}
\ No newline at end of file
import request from '@/utils/request'
import Qs from 'qs'
export function listOrder(query) {
return request({
url: '/order/list',
method: 'get',
params: query
params: query,
paramsSerializer: function(params) {
return Qs.stringify(params, { arrayFormat: 'repeat' })
}
})
}
......
......@@ -65,7 +65,8 @@ export const asyncRouterMap = [
{ path: 'address', component: _import('user/address'), name: 'address', meta: { title: '收货地址', noCache: true }},
{ path: 'collect', component: _import('user/collect'), name: 'collect', meta: { title: '会员收藏', noCache: true }},
{ path: 'footprint', component: _import('user/footprint'), name: 'footprint', meta: { title: '会员足迹', noCache: true }},
{ path: 'history', component: _import('user/history'), name: 'history', meta: { title: '搜索历史', noCache: true }}
{ path: 'history', component: _import('user/history'), name: 'history', meta: { title: '搜索历史', noCache: true }}
{ path: 'feedback', component: _import('user/feedback'), name: 'feedback', meta: { title: '意见反馈', noCache: true }}
]
},
......
<template>
<div class="app-container calendar-list-container">
<!-- 查询和其他操作 -->
<div class="filter-container">
<el-input clearable class="filter-item" style="width: 200px;" placeholder="请输入用户名" v-model="listQuery.username">
</el-input>
<el-input clearable class="filter-item" style="width: 200px;" placeholder="请输入反馈ID" v-model="listQuery.id">
</el-input>
<el-button class="filter-item" type="primary" icon="el-icon-search" @click="handleFilter">查找</el-button>
<el-button class="filter-item" type="primary" icon="el-icon-edit" @click="handleCreate">添加</el-button>
<el-button class="filter-item" type="primary" icon="el-icon-download" @click="handleDownload" :loading="downloadLoading">导出</el-button>
</div>
<!-- 查询结果 -->
<el-table size="small" :data="list" v-loading="listLoading" element-loading-text="正在查询中。。。" border fit highlight-current-row>
<el-table-column align="center" label="反馈ID" prop="id">
</el-table-column>
<el-table-column align="center" label="用户名" prop="username">
</el-table-column>
<el-table-column align="center" label="手机号码" prop="mobile">
</el-table-column>
<el-table-column align="center" label="反馈类型" prop="feedType">
</el-table-column>
<el-table-column align="center" label="反馈内容" prop="content">
</el-table-column>
<el-table-column align="center" label="反馈图片" prop="picUrls">
<template slot-scope="scope">
<img v-for="item in scope.row.picUrls" :key="item" :src="item" width="40"/>
</template>
</el-table-column>
<el-table-column align="center" label="时间" prop="addTime">
</el-table-column>
<el-table-column align="center" label="操作" width="200" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button type="primary" size="mini" @click="handleUpdate(scope.row)">编辑</el-button>
<el-button type="danger" size="mini" @click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<div class="pagination-container">
<el-pagination background @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="listQuery.page"
:page-sizes="[10,20,30,50]" :page-size="listQuery.limit" layout="total, sizes, prev, pager, next, jumper" :total="total">
</el-pagination>
</div>
<!-- 添加或修改对话框 -->
<el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible">
<el-form :rules="rules" ref="dataForm" :model="dataForm" status-icon label-position="left" label-width="100px" style='width: 400px; margin-left:50px;'>
<el-form-item label="反馈ID" prop="id">
<el-input v-model="dataForm.id"></el-input>
</el-form-item>
<el-form-item label="用户名" prop="username">
<el-input v-model="dataForm.username"></el-input>
</el-form-item>
<el-form-item label="手机号码" prop="mobile">
<el-input v-model="dataForm.mobile" type="textarea" :rows="1"></el-input>
</el-form-item>
<el-form-item label="反馈类型" prop="feedType">
<el-input v-model="dataForm.feedType" type="textarea" :rows="4"></el-input>
</el-form-item>
<el-form-item label="反馈内容" prop="content">
<el-input v-model="dataForm.content" type="textarea" :rows="4"></el-input>
</el-form-item>
<el-form-item label="反馈时间" prop="addTime">
<el-date-picker v-model="dataForm.addTime" type="date" placeholder="选择日期" value-format="yyyy-MM-dd">
</el-date-picker>
</el-form-item>
<el-form-item label="反馈图片" prop="picUrls">
<!-- <el-input v-model="dataForm.picUrls"></el-input> -->
<el-upload action="#" list-type="picture" :headers="headers" :show-file-list="false" :limit="5" :http-request="uploadPicUrls">
<el-button size="small" type="primary">点击上传</el-button>
</el-upload>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取消</el-button>
<el-button v-if="dialogStatus=='create'" type="primary" @click="createData">确定</el-button>
<el-button v-else type="primary" @click="updateData">确定</el-button>
</div>
</el-dialog>
</div>
</template>
<style>
.demo-table-expand {
font-size: 0;
}
.demo-table-expand label {
width: 200px;
color: #99a9bf;
}
.demo-table-expand .el-form-item {
margin-right: 0;
margin-bottom: 0;
}
</style>
<script>
import { listFeedback, createFeedback, updateFeedback, deleteFeedback } from '@/api/Feedback'
import { createStorage } from '@/api/storage'
import { getToken } from '@/utils/auth'
export default {
name: 'Feedback',
computed: {
headers() {
return {
'Admin-Token': getToken()
}
}
},
data() {
return {
list: undefined,
total: undefined,
listLoading: true,
listQuery: {
page: 1,
limit: 20,
username: undefined,
sort: 'add_time',
order: 'desc'
},
dataForm: {
id: undefined,
username: undefined,
mobile: undefined,
feedType: undefined,
content: undefined,
hasPicture: false,
picUrls: []
},
dialogFormVisible: false,
dialogStatus: '',
textMap: {
update: '编辑',
create: '创建'
},
rules: {
username: [{ required: true, message: '用户名不能为空', trigger: 'blur' }],
// valueId: [{ required: true, message: '反馈ID不能为空', trigger: 'blur' }],
content: [{ required: true, message: '反馈内容不能为空', trigger: 'blur' }]
},
downloadLoading: false
}
},
created() {
this.getList()
},
methods: {
getList() {
this.listLoading = true
listFeedback(this.listQuery).then(response => {
this.list = response.data.data.items
this.total = response.data.data.total
this.listLoading = false
}).catch(() => {
this.list = []
this.total = 0
this.listLoading = false
})
},
handleFilter() {
this.listQuery.page = 1
this.getList()
},
handleSizeChange(val) {
this.listQuery.limit = val
this.getList()
},
handleCurrentChange(val) {
this.listQuery.page = val
this.getList()
},
resetForm() {
this.dataForm = {
id: undefined,
username: undefined,
mobile: undefined,
feedType: undefined,
content: undefined,
picUrls: []
}
},
handleCreate() {
this.resetForm()
this.dialogStatus = 'create'
this.dialogFormVisible = true
this.$nextTick(() => {
this.$refs['dataForm'].clearValidate()
})
},
uploadPicUrls(item) {
const formData = new FormData()
formData.append('file', item.file)
createStorage(formData).then(res => {
this.dataForm.picUrls.push(res.data.data.url)
this.dataForm.hasPicture = true
}).catch(() => {
this.$message.error('上传失败,请重新上传')
})
},
createData() {
this.$refs['dataForm'].validate((valid) => {
if (valid) {
createFeedback(this.dataForm).then(response => {
this.list.unshift(response.data.data)
this.dialogFormVisible = false
this.$notify({
title: '成功',
message: '创建成功',
type: 'success',
duration: 2000
})
})
}
})
},
handleUpdate(row) {
this.dataForm = Object.assign({}, row)
this.dialogStatus = 'update'
this.dialogFormVisible = true
this.$nextTick(() => {
this.$refs['dataForm'].clearValidate()
})
},
updateData() {
this.$refs['dataForm'].validate((valid) => {
if (valid) {
updateFeedback(this.dataForm).then(() => {
for (const v of this.list) {
if (v.id === this.dataForm.id) {
const index = this.list.indexOf(v)
this.list.splice(index, 1, this.dataForm)
break
}
}
this.dialogFormVisible = false
this.$notify({
title: '成功',
message: '更新成功',
type: 'success',
duration: 2000
})
})
}
})
},
handleDelete(row) {
deleteFeedback(row).then(response => {
this.$notify({
title: '成功',
message: '删除成功',
type: 'success',
duration: 2000
})
const index = this.list.indexOf(row)
this.list.splice(index, 1)
})
},
handleDownload() {
this.downloadLoading = true
import('@/vendor/Export2Excel').then(excel => {
const tHeader = ['反馈ID', '用户名称', '反馈内容', '反馈图片列表', '反馈时间']
const filterVal = ['id', 'username', 'content', 'picUrls', 'addTime']
excel.export_json_to_excel2(tHeader, this.list, filterVal, '意见反馈信息')
this.downloadLoading = false
})
}
}
}
</script>
......@@ -25,7 +25,7 @@
<el-table-column align="center" label="性别" prop="gender">
<template slot-scope="scope">
<el-tag >{{genderDic[scope.row.status]}}</el-tag>
<el-tag >{{genderDic[scope.row.gender]}}</el-tag>
</template>
</el-table-column>
......
......@@ -102,6 +102,15 @@
<columnOverride column="pic_urls" javaType="java.lang.String[]"
typeHandler="org.linlinjava.litemall.db.mybatis.JsonStringArrayTypeHandler"/>
</table>
<table tableName="litemall_feedback">
<property name="versionColumn" value="version"/>
<generatedKey column="id" sqlStatement="MySql" identity="true"/>
<columnOverride javaType="java.time.LocalDateTime" column="add_time"/>
<columnOverride column="pic_urls" javaType="java.lang.String[]"
typeHandler="org.linlinjava.litemall.db.mybatis.JsonStringArrayTypeHandler"/>
</table>
<table tableName="litemall_footprint">
<property name="versionColumn" value="version"/>
<generatedKey column="id" sqlStatement="MySql" identity="true"/>
......
......@@ -203,6 +203,31 @@ CREATE TABLE `litemall_comment` (
) ENGINE=InnoDB AUTO_INCREMENT=1005 DEFAULT CHARSET=utf8 COMMENT='评论表';
/*!40101 SET character_set_client = @saved_cs_client */;
-- ----------------------------
-- Table structure for litemall_feedback
-- ----------------------------
DROP TABLE IF EXISTS `litemall_feedback`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
DROP TABLE IF EXISTS `litemall_feedback`;
CREATE TABLE `litemall_feedback` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL DEFAULT '0' COMMENT '用户表的用户ID',
`username` varchar(63) CHARACTER SET utf8mb4 NOT NULL DEFAULT '' COMMENT '用户名称',
`mobile` varchar(20) CHARACTER SET utf8mb4 NOT NULL DEFAULT '' COMMENT '手机号',
`feed_type` varchar(63) NOT NULL DEFAULT '' COMMENT '反馈类型',
`content` varchar(1023) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '反馈内容',
`status` int(3) NOT NULL DEFAULT '0' COMMENT '状态',
`has_picture` tinyint(1) DEFAULT '0' COMMENT '是否含有图片',
`pic_urls` varchar(1023) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '图片地址列表,采用JSON数组格式',
`add_time` datetime DEFAULT NULL COMMENT '创建时间',
`deleted` tinyint(1) DEFAULT '0' COMMENT '逻辑删除',
`version` int(11) DEFAULT '0' COMMENT '乐观锁字段',
PRIMARY KEY (`id`),
KEY `id_value` (`status`)
) ENGINE=InnoDB AUTO_INCREMENT=1007 DEFAULT CHARSET=utf8 COMMENT='意见反馈表';
--
-- Table structure for table `litemall_footprint`
--
......
package org.linlinjava.litemall.db.dao;
import org.apache.ibatis.annotations.Param;
import org.linlinjava.litemall.db.domain.LitemallFeedback;
import org.linlinjava.litemall.db.domain.LitemallFeedbackExample;
import java.util.List;
public interface LitemallFeedbackMapper {
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table litemall_feedback
*
* @mbg.generated
*/
long countByExample(LitemallFeedbackExample example);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table litemall_feedback
*
* @mbg.generated
* @project https://github.com/itfsw/mybatis-generator-plugin
*/
int deleteWithVersionByExample(@Param("version") Integer version, @Param("example") LitemallFeedbackExample example);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table litemall_feedback
*
* @mbg.generated
*/
int deleteByExample(LitemallFeedbackExample example);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table litemall_feedback
*
* @mbg.generated
* @project https://github.com/itfsw/mybatis-generator-plugin
*/
int deleteWithVersionByPrimaryKey(@Param("version") Integer version, @Param("key") Integer key);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table litemall_feedback
*
* @mbg.generated
*/
int deleteByPrimaryKey(Integer id);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table litemall_feedback
*
* @mbg.generated
*/
int insert(LitemallFeedback record);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table litemall_feedback
*
* @mbg.generated
*/
int insertSelective(LitemallFeedback record);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table litemall_feedback
*
* @mbg.generated
* @project https://github.com/itfsw/mybatis-generator-plugin
*/
LitemallFeedback selectOneByExample(LitemallFeedbackExample example);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table litemall_feedback
*
* @mbg.generated
* @project https://github.com/itfsw/mybatis-generator-plugin
*/
LitemallFeedback selectOneByExampleSelective(@Param("example") LitemallFeedbackExample example, @Param("selective") LitemallFeedback.Column... selective);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table litemall_feedback
*
* @mbg.generated
* @project https://github.com/itfsw/mybatis-generator-plugin
*/
List<LitemallFeedback> selectByExampleSelective(@Param("example") LitemallFeedbackExample example, @Param("selective") LitemallFeedback.Column... selective);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table litemall_feedback
*
* @mbg.generated
*/
List<LitemallFeedback> selectByExample(LitemallFeedbackExample example);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table litemall_feedback
*
* @mbg.generated
* @project https://github.com/itfsw/mybatis-generator-plugin
*/
LitemallFeedback selectByPrimaryKeySelective(@Param("id") Integer id, @Param("selective") LitemallFeedback.Column... selective);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table litemall_feedback
*
* @mbg.generated
*/
LitemallFeedback selectByPrimaryKey(Integer id);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table litemall_feedback
*
* @mbg.generated
* @project https://github.com/itfsw/mybatis-generator-plugin
*/
LitemallFeedback selectByPrimaryKeyWithLogicalDelete(@Param("id") Integer id, @Param("andLogicalDeleted") boolean andLogicalDeleted);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table litemall_feedback
*
* @mbg.generated
* @project https://github.com/itfsw/mybatis-generator-plugin
*/
int updateWithVersionByExample(@Param("version") Integer version, @Param("record") LitemallFeedback record, @Param("example") LitemallFeedbackExample example);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table litemall_feedback
*
* @mbg.generated
* @project https://github.com/itfsw/mybatis-generator-plugin
*/
int updateWithVersionByExampleSelective(@Param("version") Integer version, @Param("record") LitemallFeedback record, @Param("example") LitemallFeedbackExample example);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table litemall_feedback
*
* @mbg.generated
*/
int updateByExampleSelective(@Param("record") LitemallFeedback record, @Param("example") LitemallFeedbackExample example);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table litemall_feedback
*
* @mbg.generated
*/
int updateByExample(@Param("record") LitemallFeedback record, @Param("example") LitemallFeedbackExample example);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table litemall_feedback
*
* @mbg.generated
* @project https://github.com/itfsw/mybatis-generator-plugin
*/
int updateWithVersionByPrimaryKey(@Param("version") Integer version, @Param("record") LitemallFeedback record);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table litemall_feedback
*
* @mbg.generated
* @project https://github.com/itfsw/mybatis-generator-plugin
*/
int updateWithVersionByPrimaryKeySelective(@Param("version") Integer version, @Param("record") LitemallFeedback record);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table litemall_feedback
*
* @mbg.generated
*/
int updateByPrimaryKeySelective(LitemallFeedback record);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table litemall_feedback
*
* @mbg.generated
*/
int updateByPrimaryKey(LitemallFeedback record);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table litemall_feedback
*
* @mbg.generated
* @project https://github.com/itfsw/mybatis-generator-plugin
*/
int logicalDeleteByExample(@Param("example") LitemallFeedbackExample example);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table litemall_feedback
*
* @mbg.generated
* @project https://github.com/itfsw/mybatis-generator-plugin
*/
int logicalDeleteByPrimaryKey(Integer id);
}
\ No newline at end of file
package org.linlinjava.litemall.db.service;
import com.github.pagehelper.PageHelper;
import org.linlinjava.litemall.db.dao.LitemallFeedbackMapper;
import org.linlinjava.litemall.db.domain.LitemallFeedback;
import org.linlinjava.litemall.db.domain.LitemallFeedbackExample;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.util.List;
/**
* @author Yogeek
* @date 2018/8/27 11:39
*/
@Service
public class LitemallFeedbackService {
@Autowired
private LitemallFeedbackMapper feedbackMapper;
//提交
public Integer add(LitemallFeedback feedback) {
return feedbackMapper.insertSelective(feedback);
}
public List<LitemallFeedback> querySelective(Integer userId, String username, Integer page, Integer limit, String sort, String order) {
LitemallFeedbackExample example = new LitemallFeedbackExample();
LitemallFeedbackExample.Criteria criteria = example.createCriteria();
if(userId != null){
criteria.andUserIdEqualTo(userId);
}
if(!StringUtils.isEmpty(username)){
criteria.andUsernameLike("%" + username + "%");
}
criteria.andDeletedEqualTo(false);
if (!StringUtils.isEmpty(sort) && !StringUtils.isEmpty(order)) {
example.setOrderByClause(sort + " " + order);
}
PageHelper.startPage(page, limit);
return feedbackMapper.selectByExample(example);
}
public int countSelective(Integer userId, String username, Integer page, Integer limit, String sort, String order) {
LitemallFeedbackExample example = new LitemallFeedbackExample();
LitemallFeedbackExample.Criteria criteria = example.createCriteria();
if(userId != null){
criteria.andUserIdEqualTo(userId);
}
if(!StringUtils.isEmpty(username)){
criteria.andUsernameLike("%" + username + "%");
}
criteria.andDeletedEqualTo(false);
return (int)feedbackMapper.countByExample(example);
}
public LitemallFeedback findById(Integer id) {
return feedbackMapper.selectByPrimaryKey(id);
}
public void updateById(LitemallFeedback feedback) {
feedbackMapper.updateByPrimaryKeySelective(feedback);
}
public void delete(Integer id) {
feedbackMapper.logicalDeleteByPrimaryKey(id);
}
}
......@@ -49,6 +49,12 @@
<artifactId>weixin-java-miniapp</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.45</version>
</dependency>
</dependencies>
<build>
......
package org.linlinjava.litemall.wx.web;
import com.alibaba.fastjson.JSONObject;
import org.linlinjava.litemall.core.util.RegexUtil;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.db.domain.LitemallFeedback;
import org.linlinjava.litemall.db.domain.LitemallUser;
import org.linlinjava.litemall.db.service.LitemallFeedbackService;
import org.linlinjava.litemall.db.service.LitemallUserService;
import org.linlinjava.litemall.wx.annotation.LoginUser;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.time.LocalDateTime;
/**
* @author Yogeek
* @date 2018/8/25 14:10
*/
@RestController
@RequestMapping("/wx/feedback")
@Validated
public class WxFeedbackController {
private final Log logger = LogFactory.getLog(WxFeedbackController.class);
@Autowired
private LitemallFeedbackService feedbackService;
@Autowired
protected HttpServletRequest request;
@Autowired
private LitemallUserService userService;
/**
* 意见反馈
*/
@PostMapping("submit")
@ResponseBody
public Object save(@LoginUser Integer userId){
if(userId == null){
return ResponseUtil.unlogin();
}
LitemallUser user = userService.findById(userId);
String username = user.getUsername();
//获取客户端对象
JSONObject feedbackJson = this.getJsonRequest();
if (null != feedbackJson) {
LitemallFeedback feedback = new LitemallFeedback();
String mobile = feedbackJson.getString("mobile");
// 测试手机号码是否正确
if (!RegexUtil.isMobileExact(mobile)) {
return ResponseUtil.badArgument();
}
String[] feedType = new String [] {"请选择反馈类型", "商品相关", "功能异常", "优化建议", "其他"};
int index = feedbackJson.getInteger("index");
String content = feedbackJson.getString("content");
feedback.setUserId(userId);
feedback.setUsername(username);
feedback.setMobile(mobile);
feedback.setAddTime(LocalDateTime.now());
feedback.setFeedType(feedType[index]);
//状态默认是0,1表示状态已发生变化
feedback.setStatus(1);
feedback.setContent(content);
feedbackService.add(feedback);
return ResponseUtil.ok("感谢您的反馈");
}
return ResponseUtil.badArgument();
}
private JSONObject getJsonRequest() {
JSONObject result = null;
StringBuilder sb = new StringBuilder();
try (BufferedReader reader = request.getReader();) {
char[] buff = new char[1024];
int len;
while ((len = reader.read(buff)) != -1) {
sb.append(buff, 0, len);
}
result = JSONObject.parseObject(sb.toString());
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
}
......@@ -7,6 +7,7 @@
"pages/ucenter/index/index",
"pages/ucenter/address/address",
"pages/ucenter/addressAdd/addressAdd",
"pages/ucenter/feedback/feedback",
"pages/ucenter/footprint/footprint",
"pages/ucenter/order/order",
"pages/ucenter/orderDetail/orderDetail",
......@@ -50,25 +51,25 @@
"list": [
{
"pagePath": "pages/index/index",
"iconPath": "static/images/ic_menu_choice_nor.png",
"iconPath": "static/images/home.png",
"selectedIconPath": "static/images/home@selected.png",
"text": "首页"
},
{
"pagePath": "pages/catalog/catalog",
"iconPath": "static/images/ic_menu_sort_nor.png",
"iconPath": "static/images/category.png",
"selectedIconPath": "static/images/category@selected.png",
"text": "分类"
},
{
"pagePath": "pages/cart/cart",
"iconPath": "static/images/ic_menu_shoping_nor.png",
"iconPath": "static/images/cart.png",
"selectedIconPath": "static/images/cart@selected.png",
"text": "购物车"
},
{
"pagePath": "pages/ucenter/index/index",
"iconPath": "static/images/ic_menu_me_nor.png",
"iconPath": "static/images/my.png",
"selectedIconPath": "static/images/my@selected.png",
"text": "个人"
}
......
.form-box{
width: 100%;
height: auto;
overflow: hidden;
padding: 0 40rpx;
margin-top: 200rpx;
background: #fff;
.form-box {
width: 100%;
height: auto;
overflow: hidden;
padding: 0 40rpx;
margin-top: 200rpx;
background: #fff;
}
.form-item{
position: relative;
background: #fff;
height: 96rpx;
border-bottom: 1px solid #d9d9d9;
.form-item {
position: relative;
background: #fff;
height: 96rpx;
border-bottom: 1px solid #d9d9d9;
}
.form-item .username, .form-item .password, .form-item .code{
position: absolute;
top: 26rpx;
left: 0;
display: block;
width: 100%;
height: 44rpx;
background: #fff;
color: #333;
font-size: 30rpx;
.form-item .username, .form-item .password, .form-item .code {
position: absolute;
top: 26rpx;
left: 0;
display: block;
width: 100%;
height: 44rpx;
background: #fff;
color: #333;
font-size: 30rpx;
}
.form-item-code{
margin-top:32rpx;
height: auto;
overflow: hidden;
width: 100%;
.form-item-code {
margin-top: 32rpx;
height: auto;
overflow: hidden;
width: 100%;
}
.form-item-code .form-item{
float: left;
width: 350rpx;
.form-item-code .form-item {
float: left;
width: 350rpx;
}
.form-item-code .code-img{
float: right;
margin-top: 4rpx;
height: 88rpx;
width: 236rpx;
.form-item-code .code-img {
float: right;
margin-top: 4rpx;
height: 88rpx;
width: 236rpx;
}
.form-item .clear{
position: absolute;
top: 26rpx;
right: 18rpx;
z-index: 2;
display: block;
background: #fff;
height: 44rpx;
width: 44rpx;
.form-item .clear {
position: absolute;
top: 26rpx;
right: 18rpx;
z-index: 2;
display: block;
background: #fff;
height: 44rpx;
width: 44rpx;
}
.login-btn{
margin: 60rpx 0 40rpx 0;
height: 96rpx;
line-height: 96rpx;
font-size: 30rpx;
width: 100%;
background: #b4282d;
border-radius: 6rpx;
.login-btn {
margin: 60rpx 0 40rpx 0;
height: 96rpx;
line-height: 96rpx;
font-size: 30rpx;
border-radius: 6rpx;
width: 90%;
color: #fff;
right: 0;
display: flex;
justify-content: center;
align-items: center;
position: flex;
bottom: 0;
left: 0;
padding: 0;
margin-left: 5%;
text-align: center;
/* padding-left: -5rpx; */
border-top-left-radius: 50rpx;
border-bottom-left-radius: 50rpx;
border-top-right-radius: 50rpx;
border-bottom-right-radius: 50rpx;
letter-spacing: 3rpx;
background-image: linear-gradient(to right, #9a9ba1 0%, #9a9ba1 100%);
}
.form-item-text{
height: 35rpx;
width: 100%;
.form-item-text {
height: 35rpx;
width: 100%;
}
.form-item-text .register{
display: block;
height: 34rpx;
float: left;
font-size: 28rpx;
.form-item-text .register {
display: block;
height: 34rpx;
float: left;
font-size: 28rpx;
}
.form-item-text .reset{
display: block;
height: 34rpx;
float: right;
font-size: 28rpx;
}
\ No newline at end of file
.form-item-text .reset {
display: block;
height: 34rpx;
float: right;
font-size: 28rpx;
}
.login-box{
width: 100%;
height: auto;
overflow: hidden;
padding: 0 40rpx;
margin-top: 200rpx;
background: #fff;
.login-box {
width: 100%;
height: auto;
overflow: hidden;
padding: 0 40rpx;
margin-top: 200rpx;
background: #fff;
}
.wx-login-btn{
margin: 60rpx 0 40rpx 0;
height: 96rpx;
line-height: 96rpx;
font-size: 30rpx;
width: 100%;
border-radius: 6rpx;
.wx-login-btn {
margin: 60rpx 0 40rpx 0;
height: 96rpx;
line-height: 96rpx;
font-size: 30rpx;
border-radius: 6rpx;
width: 90%;
color: #fff;
right: 0;
display: flex;
justify-content: center;
align-items: center;
position: flex;
bottom: 0;
left: 0;
padding: 0;
margin-left: 5%;
text-align: center;
/* padding-left: -5rpx; */
border-top-left-radius: 50rpx;
border-bottom-left-radius: 50rpx;
border-top-right-radius: 50rpx;
border-bottom-right-radius: 50rpx;
letter-spacing: 3rpx;
}
.account-login-btn{
margin: 60rpx 0 40rpx 0;
height: 96rpx;
line-height: 96rpx;
font-size: 30rpx;
width: 100%;
border-radius: 6rpx;
}
\ No newline at end of file
.account-login-btn {
width: 90%;
margin: 0 auto;
color: #fff;
font-size: 30rpx;
height: 96rpx;
line-height: 96rpx;
right: 0;
display: flex;
justify-content: center;
align-items: center;
position: flex;
bottom: 0;
left: 0;
border-radius: 0;
padding: 0;
margin-left: 5%;
text-align: center;
/* padding-left: -5rpx; */
border-top-left-radius: 50rpx;
border-bottom-left-radius: 50rpx;
border-top-right-radius: 50rpx;
border-bottom-right-radius: 50rpx;
letter-spacing: 3rpx;
background-image: linear-gradient(to right, #9a9ba1 0%, #9a9ba1 100%);
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment