增加快捷回复功能/删除组和回复内容

pull/23/head
taoshihan1991 4 years ago
parent 28780f6e8c
commit 4733c8133e

@ -139,11 +139,12 @@ CREATE TABLE `reply_group` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8|
DROP TABLE IF EXISTS `reply_item`|
CREATE TABLE `reply_item` (
`id` int(11) NOT NULL,
`id` int(11) NOT NULL AUTO_INCREMENT,
`content` varchar(1024) NOT NULL DEFAULT '',
`group_id` int(11) NOT NULL DEFAULT '0',
`user_id` int(11) NOT NULL DEFAULT '0',
`user_id` varchar(50) NOT NULL DEFAULT '',
`item_name` varchar(50) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`),
KEY `group_id` (`group_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8|

@ -9,6 +9,10 @@ import (
type ReplyForm struct {
GroupName string `form:"group_name" binding:"required"`
}
type ReplyContentForm struct {
GroupId string `form:"group_id" binding:"required"`
Content string `form:"content" binding:"required"`
}
func GetReplys(c *gin.Context) {
kefuId, _ := c.Get("kefu_name")
@ -22,11 +26,53 @@ func GetReplys(c *gin.Context) {
}
func PostReply(c *gin.Context) {
var replyForm ReplyForm
kefuId, _ := c.Get("kefu_name")
err := c.Bind(&replyForm)
if err != nil {
c.JSON(200, gin.H{
"code": 400,
"msg": "error:" + err.Error(),
})
return
}
models.CreateReplyGroup(replyForm.GroupName, kefuId.(string))
c.JSON(200, gin.H{
"code": 200,
"msg": "ok",
})
}
func PostReplyContent(c *gin.Context) {
var replyContentForm ReplyContentForm
kefuId, _ := c.Get("kefu_name")
err := c.Bind(&replyContentForm)
if err != nil {
c.JSON(400, gin.H{
"code": 200,
"msg": "error:" + err.Error(),
})
return
}
models.CreateReplyContent(replyContentForm.GroupId, kefuId.(string), replyContentForm.Content)
c.JSON(200, gin.H{
"code": 200,
"msg": "ok",
})
}
func DelReplyContent(c *gin.Context) {
kefuId, _ := c.Get("kefu_name")
id := c.Query("id")
models.DeleteReplyContent(id, kefuId.(string))
c.JSON(200, gin.H{
"code": 200,
"msg": "ok",
})
}
func DelReplyGroup(c *gin.Context) {
kefuId, _ := c.Get("kefu_name")
id := c.Query("id")
models.DeleteReplyGroup(id, kefuId.(string))
c.JSON(200, gin.H{
"code": 200,
"msg": "ok",
})
}

@ -5,18 +5,30 @@ type ReplyItem struct {
Content string `json:"item_content"`
GroupId string `json:"group_id"`
ItemName string `json:"item_name"`
UserId string `json:"user_id"`
}
type ReplyGroup struct {
Id string `json:"group_id"`
GroupName string `json:"group_name"`
UserId string `json:"user_id"`
Items []ReplyItem `json:"items"`
Id string `json:"group_id"`
GroupName string `json:"group_name"`
UserId string `json:"user_id"`
Items []*ReplyItem `json:"items";"`
}
func FindReplyByUserId(userId interface{}) ReplyGroup {
var replyGroup ReplyGroup
DB.Raw("select a.*,b.* from reply_group a left join reply_item b on a.id=b.group_id where a.user_id=? ", userId).Scan(&replyGroup)
return replyGroup
func FindReplyByUserId(userId interface{}) []*ReplyGroup {
var replyGroups []*ReplyGroup
//DB.Raw("select a.*,b.* from reply_group a left join reply_item b on a.id=b.group_id where a.user_id=? ", userId).Scan(&replyGroups)
var replyItems []*ReplyItem
DB.Where("user_id = ?", userId).Find(&replyGroups)
DB.Where("user_id = ?", userId).Find(&replyItems)
temp := make(map[string]*ReplyGroup)
for _, replyGroup := range replyGroups {
replyGroup.Items = make([]*ReplyItem, 0)
temp[replyGroup.Id] = replyGroup
}
for _, replyItem := range replyItems {
temp[replyItem.GroupId].Items = append(temp[replyItem.GroupId].Items, replyItem)
}
return replyGroups
}
func CreateReplyGroup(groupName string, userId string) {
g := &ReplyGroup{
@ -25,3 +37,19 @@ func CreateReplyGroup(groupName string, userId string) {
}
DB.Create(g)
}
func CreateReplyContent(groupId string, userId string, content string) {
g := &ReplyItem{
GroupId: groupId,
UserId: userId,
Content: content,
ItemName: "",
}
DB.Create(g)
}
func DeleteReplyContent(id string, userId string) {
DB.Where("user_id = ? and id = ?", userId, id).Delete(ReplyItem{})
}
func DeleteReplyGroup(id string, userId string) {
DB.Where("user_id = ? and id = ?", userId, id).Delete(ReplyGroup{})
DB.Where("user_id = ? and group_id = ?", userId, id).Delete(ReplyItem{})
}

@ -83,6 +83,9 @@ func InitApiRouter(engine *gin.Engine) {
engine.GET("/config", controller.GetConfig)
engine.GET("/replys", middleware.JwtApiMiddleware, controller.GetReplys)
engine.POST("/reply", middleware.JwtApiMiddleware, controller.PostReply)
engine.POST("/reply_content", middleware.JwtApiMiddleware, controller.PostReplyContent)
engine.DELETE("/reply_content", middleware.JwtApiMiddleware, controller.DelReplyContent)
engine.DELETE("/reply", middleware.JwtApiMiddleware, controller.DelReplyGroup)
//微信接口
engine.GET("/micro_program", middleware.JwtApiMiddleware, controller.GetCheckWeixinSign)
}

@ -341,6 +341,7 @@
background: #fff;
border: solid 1px #e6e6e6;
margin-top: 5px;
margin-bottom: 50px;
}
.replyItem:hover{
background-color: #f0f9eb;

@ -4,7 +4,7 @@
<meta name="description" content="">
<meta name="author" content="陶士涵">
<title>聊天界面</title>
<link rel="stylesheet" href="/static/css/common.css">
<link rel="stylesheet" href="/static/css/common.css?v=0.3.7">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/element-ui@2.13.1/lib/theme-chalk/index.css">
<script src="/static/js/functions.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
@ -201,13 +201,13 @@
</div>
<div class="replyContent">
<el-collapse>
<el-collapse-item title="客服营销" name="1">
<div class="replyItem">与现实生活一致:与现实生活的流程、逻辑保持一致,遵循用户习惯的语言和概念;</div>
<div class="replyItem">在界面中一致:所有的元素和结构需保持一致,比如:设计样式、图标和文本、元素的位置等。</div>
</el-collapse-item>
<el-collapse-item title="通用话术" name="2">
<div class="replyItem">控制反馈:通过界面样式和交互动效让用户可以清晰的感知自己的操作;</div>
<div class="replyItem">页面反馈:操作后,通过页面元素的变化清晰地展现当前状态。</div>
<el-collapse-item v-for="reply in replys" :key="reply.group_id" :title="reply.group_name" :name="reply.group_id">
<template slot="title">
<i class="header-icon el-icon-info"></i>&nbsp;<{reply.group_name}>
</template>
<div class="replyItem" @click="messageContent=item.item_content" v-for="item in reply.items" ><{item.item_content}> &nbsp;&nbsp;<el-button @click="deleteReplyContent(item.item_id)" type="text">删除</el-button></div>
<el-button @click="replyContentDialog=true;groupName=reply.group_name;groupId=reply.group_id" type="text">+添加回复内容</el-button>
<el-button @click="deleteReplyGroup(reply.group_id)" type="text">-删除组</el-button>
</el-collapse-item>
</el-collapse>
</div>
@ -254,7 +254,7 @@
</span>
</el-dialog>
<!--//转接-->
<!--转接-->
<!--回复分组-->
<el-dialog
title="添加分组"
:visible.sync="replyGroupDialog"
@ -267,9 +267,23 @@
<el-button @click="replyGroupDialog = false">取 消</el-button>
</span>
</el-dialog>
<!--//转接-->
<!--//回复分组-->
<!--回复内容-->
<el-dialog
title="添加回复内容"
:visible.sync="replyContentDialog"
width="30%"
top="0"
>
<el-input type="textarea" v-model="replyContent"></el-input>
<span slot="footer" class="dialog-footer">
<el-button @click="addReplyContent">保 存</el-button>
<el-button @click="replyContentDialog = false">取 消</el-button>
</span>
</el-dialog>
<!--//回复内容-->
</template>
</div>
</body>
<script src="/static/js/chat-main.js?v=0.3.6"></script>
<script src="/static/js/chat-main.js?v=0.3.7"></script>
</html>

@ -38,7 +38,12 @@ var app=new Vue({
transKefuDialog:false,
otherKefus:[],
replyGroupDialog:false,
replyContentDialog:false,
groupName:"",
groupId:"",
replys:[],
replyContent:"",
},
methods: {
//跳转
@ -616,9 +621,42 @@ var app=new Vue({
//保存回复分组
addReplyGroup(){
var _this=this;
this.sendAjax("/reply","post",{group_name:this.group_name},function(result){
this.sendAjax("/reply","post",{group_name:_this.groupName},function(result){
//_this.otherKefus=result;
_this.replyGroupDialog = false
_this.groupName="";
_this.getReplys();
});
},
//添加回复内容
addReplyContent(){
var _this=this;
this.sendAjax("/reply_content","post",{group_id:_this.groupId,content:_this.replyContent},function(result){
//_this.otherKefus=result;
_this.replyContentDialog = false
_this.replyContent="";
_this.getReplys();
});
},
//获取快捷回复
getReplys(){
var _this=this;
this.sendAjax("/replys","get",{},function(result){
_this.replys=result;
});
},
//删除回复
deleteReplyGroup(id){
var _this=this;
this.sendAjax("/reply?id="+id,"delete",{},function(result){
_this.getReplys();
});
},
//删除回复
deleteReplyContent(id){
var _this=this;
this.sendAjax("/reply_content?id="+id,"delete",{},function(result){
_this.getReplys();
});
},
sendAjax(url,method,params,callback){
@ -628,9 +666,18 @@ var app=new Vue({
url: url,
data:params,
headers: {
"Content-Type":"",
"token": localStorage.getItem("token")
},
error:function(res){
var data=JSON.parse(res.responseText);
console.log(data);
if(data.code!=200){
_this.$message({
message: data.msg,
type: 'error'
});
}
},
success: function(data) {
if(data.code!=200){
_this.$message({
@ -654,6 +701,7 @@ var app=new Vue({
this.initJquery();
this.getKefuInfo();
this.getOnlineVisitors();
this.getReplys();
//心跳
this.ping();
}

Loading…
Cancel
Save