mirror of
https://github.com/chatopera/cosin.git
synced 2025-08-01 16:38:02 +08:00
#70 支持管理机器人
This commit is contained in:
parent
18dc88f514
commit
771f273546
@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 Chatopera Inc, <https://www.chatopera.com>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.chatopera.cc.app.handler.apps.chatbot;
|
||||||
|
|
||||||
|
import com.chatopera.cc.app.handler.Handler;
|
||||||
|
import com.chatopera.cc.app.model.Chatbot;
|
||||||
|
import com.chatopera.cc.app.model.SNSAccount;
|
||||||
|
import com.chatopera.cc.app.model.User;
|
||||||
|
import com.chatopera.cc.app.persistence.repository.ChatbotRepository;
|
||||||
|
import com.chatopera.cc.app.persistence.repository.SNSAccountRepository;
|
||||||
|
import com.chatopera.cc.util.Menu;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.ModelMap;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.validation.Valid;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
@RequestMapping(value = "/apps/chatbot")
|
||||||
|
public class ChatbotController extends Handler {
|
||||||
|
@Autowired
|
||||||
|
private ChatbotRepository chatbotRes;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SNSAccountRepository snsAccountRes;
|
||||||
|
|
||||||
|
@RequestMapping(value = "/index")
|
||||||
|
@Menu(type = "chatbot", subtype = "index", access = true)
|
||||||
|
public ModelAndView index(ModelMap map, HttpServletRequest request) {
|
||||||
|
|
||||||
|
return request(super.createAppsTempletResponse("/apps/chatbot/index"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping(value = "/edit")
|
||||||
|
@Menu(type = "chatbot", subtype = "index", access = true)
|
||||||
|
public ModelAndView eidt(ModelMap map, HttpServletRequest request, @Valid String id) {
|
||||||
|
User curruser = super.getUser(request);
|
||||||
|
|
||||||
|
ModelAndView view = request(super.createAppsTempletResponse("/apps/chatbot/edit"));
|
||||||
|
if (id != null) {
|
||||||
|
Chatbot c = chatbotRes.findOne(id);
|
||||||
|
SNSAccount snsAccount = snsAccountRes.findBySnsidAndOrgi(c.getSnsAccountIdentifier(), curruser.getOrgi());
|
||||||
|
view.addObject("snsurl", snsAccount.getBaseURL());
|
||||||
|
view.addObject("bot", c);
|
||||||
|
}
|
||||||
|
|
||||||
|
view.addObject("id", id);
|
||||||
|
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,165 @@
|
|||||||
|
<style>
|
||||||
|
#create {
|
||||||
|
margin: 10px;
|
||||||
|
border-top: 1px solid #EEEEEE;
|
||||||
|
padding-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#create input {
|
||||||
|
width: 400px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-12">
|
||||||
|
<h1>机器人列表</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-12">
|
||||||
|
<div id="create">
|
||||||
|
<form class="layui-form uk-form" style="width: 700px;margin: auto;">
|
||||||
|
<input id="id" type="hidden" name="id" value="${id}">
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">网站渠道</label>
|
||||||
|
<div class="layui-input-inline">
|
||||||
|
<#if id!=null>
|
||||||
|
<input type="text" name="snsurl" required lay-verify="required" value="${snsurl}"
|
||||||
|
autocomplete="off" class="layui-input" disabled>
|
||||||
|
<#else>
|
||||||
|
<select id="snsid" name="snsid" lay-verify="required">
|
||||||
|
<option></option>
|
||||||
|
</select>
|
||||||
|
</#if>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">智能问答引擎地址</label>
|
||||||
|
<div class="layui-input-inline">
|
||||||
|
<input type="text" name="baseUrl" required lay-verify="required" placeholder="请输入智能问答引擎地址"
|
||||||
|
autocomplete="off" class="layui-input" value="${bot.baseUrl}" <#if id!=null>disabled</#if>>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">名称</label>
|
||||||
|
<div class="layui-input-inline">
|
||||||
|
<input type="text" name="name" required lay-verify="required" placeholder="请输入名称" autocomplete="off"
|
||||||
|
class="layui-input" value="${bot.name}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">语言</label>
|
||||||
|
<div class="layui-input-inline">
|
||||||
|
<select name="primaryLanguage" lay-verify="required">
|
||||||
|
<option value="zh_CN" <#if bot.primaryLanguage=="zh_CN">selected="selected"</#if>>中文</option>
|
||||||
|
<option value="en_US" <#if bot.primaryLanguage=="en_US">selected="selected"</#if>>英文</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">兜底回复</label>
|
||||||
|
<div class="layui-input-inline">
|
||||||
|
<input type="text" name="fallback" required lay-verify="required" autocomplete="off" value="${bot.fallback}"
|
||||||
|
class="layui-input">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">工作模式</label>
|
||||||
|
<div class="layui-input-inline">
|
||||||
|
<select name="workmode" lay-verify="required">
|
||||||
|
<option <#if bot.workmode=="机器人客服优先">selected="selected"</#if>>机器人客服优先</option>
|
||||||
|
<option <#if bot.workmode=="人工客服优先">selected="selected"</#if>>人工客服优先</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">描述</label>
|
||||||
|
<div class="layui-input-inline">
|
||||||
|
<input type="text" name="description" required lay-verify="required" autocomplete="off" value="${bot.description}"
|
||||||
|
class="layui-input">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<div class="layui-input-inline">
|
||||||
|
<button class="layui-btn" lay-submit lay-filter="save">保存</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
function request(data, cb) {
|
||||||
|
var postfix = '/api/';
|
||||||
|
var payload = {
|
||||||
|
url: postfix + 'chatbot',
|
||||||
|
method: 'POST',
|
||||||
|
contentType: 'application/json;charset=UTF-8',
|
||||||
|
headers: {
|
||||||
|
authorization: $.cookie('authorization')
|
||||||
|
},
|
||||||
|
dataType: 'json',
|
||||||
|
data: JSON.stringify(data)
|
||||||
|
};
|
||||||
|
|
||||||
|
$.ajax(payload)
|
||||||
|
.done(function (data) {
|
||||||
|
console.log('Rest api 返回的值:', data);
|
||||||
|
if (data.rc == 0) {
|
||||||
|
cb(null, data.data);
|
||||||
|
} else {
|
||||||
|
cb(data.error);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.fail(function (jqXHR, textStatus) {
|
||||||
|
console.error('Rest api 返回error:', jqXHR);
|
||||||
|
cb(textStatus);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
layui.use(['form'], function () {
|
||||||
|
var form = layui.form();
|
||||||
|
form.on('submit(save)', function (data) {
|
||||||
|
let field = data.field;
|
||||||
|
|
||||||
|
var submitFinish = function (err, bot) {
|
||||||
|
if (err) {
|
||||||
|
console.error(err);
|
||||||
|
} else {
|
||||||
|
layer.open({
|
||||||
|
title: '提示'
|
||||||
|
, content: '保存成功'
|
||||||
|
});
|
||||||
|
location.href = '/apps/chatbot/index.html';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (field.id) {
|
||||||
|
field.ops = 'update';
|
||||||
|
request(field, submitFinish);
|
||||||
|
} else {
|
||||||
|
field.ops = 'create';
|
||||||
|
request(field, submitFinish);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(data.field);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!$('#id').val()) {
|
||||||
|
request({
|
||||||
|
ops: 'vacant'
|
||||||
|
}, function (err, list) {
|
||||||
|
if (err) {
|
||||||
|
console.error(err)
|
||||||
|
} else {
|
||||||
|
var options = $.map(list, function (r) {
|
||||||
|
return '<option value="' + r.snsid + '">' + r.snsurl + '</option>';
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#snsid').html(options);
|
||||||
|
form.render('select');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
@ -0,0 +1,129 @@
|
|||||||
|
<style>
|
||||||
|
#create {
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#create input {
|
||||||
|
width: 400px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div class="layui-layout-body">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-12">
|
||||||
|
<h1>机器人列表
|
||||||
|
<div style="float: right;" class="ukefu-bt-text-content">
|
||||||
|
<button class="layui-btn layui-btn-samll green" onclick="showCreate()">新建机器人</button>
|
||||||
|
</div>
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-12">
|
||||||
|
<table class="layui-table" lay-skin="line">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>机器人名称</th>
|
||||||
|
<th>网站渠道</th>
|
||||||
|
<th>是否开启</th>
|
||||||
|
<th style="white-space:nowrap;" nowrap="nowrap">操作</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="bots">
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
layui.use(['form'], function () {
|
||||||
|
var form = layui.form()
|
||||||
|
|
||||||
|
function request(path, data) {
|
||||||
|
var postfix = '/api/';
|
||||||
|
var payload = {
|
||||||
|
url: postfix + path,
|
||||||
|
method: 'POST',
|
||||||
|
contentType: 'application/json;charset=UTF-8',
|
||||||
|
headers: {
|
||||||
|
authorization: $.cookie('authorization')
|
||||||
|
},
|
||||||
|
dataType: 'json',
|
||||||
|
data: JSON.stringify(data)
|
||||||
|
};
|
||||||
|
return new Promise(function (resolve, reject) {
|
||||||
|
$.ajax(payload)
|
||||||
|
.done(function (data) {
|
||||||
|
console.log('Rest api 返回的值:', data);
|
||||||
|
if (data.rc == 0) {
|
||||||
|
resolve(data.data);
|
||||||
|
} else {
|
||||||
|
reject(data.error);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.fail(function (jqXHR, textStatus) {
|
||||||
|
console.error('Rest api 返回error:', jqXHR);
|
||||||
|
reject(textStatus)
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function query(p, ps) {
|
||||||
|
request('chatbot?p=' + (p || 1) + '&ps=' + (ps || 10), { ops: 'fetch' }).then(function (rows) {
|
||||||
|
var tds = $.map(rows, function (r) {
|
||||||
|
var edit = $('<a href="edit.html?id=' + r.id + '" data-width="550" data-height="300"><i class="layui-icon"></i>编辑</a>');
|
||||||
|
|
||||||
|
var remove = $('<a style="margin-left:10px;"><i class="layui-icon" style="color:red;">ဆ</i>删除</a>').click(function () {
|
||||||
|
var lindex = layer.confirm('请确认是否删除?', {
|
||||||
|
btn: ['确认', '删除']
|
||||||
|
}, function () {
|
||||||
|
console.log('ok', r.id)
|
||||||
|
window.remove(r.id);
|
||||||
|
window.init();
|
||||||
|
layer.close(lindex);
|
||||||
|
}, function () {
|
||||||
|
console.log('cancel', r.id)
|
||||||
|
layer.close(lindex);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
var isEnabled = $('<td><input type="checkbox" lay-skin="switch" lay-text="开启|关闭" ' + (r.enabled ? 'checked' : '') + '></td>');
|
||||||
|
isEnabled.change(function () {
|
||||||
|
change(r.id, $(this).find('input').prop('checked'));
|
||||||
|
})
|
||||||
|
|
||||||
|
var rows = [
|
||||||
|
$('<td>' + r.name + '</td>'),
|
||||||
|
$('<td>' + r.snsurl + '</td>'),
|
||||||
|
isEnabled,
|
||||||
|
$('<td style="white-space:nowrap;" nowrap="nowrap"></td>').html([edit, remove])
|
||||||
|
];
|
||||||
|
|
||||||
|
var tr = $('<tr></tr>');
|
||||||
|
tr.html(rows);
|
||||||
|
return tr;
|
||||||
|
})
|
||||||
|
|
||||||
|
$('#bots').html(tds);
|
||||||
|
form.render();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function remove(id) {
|
||||||
|
return request('chatbot', { ops: 'delete', id: id })
|
||||||
|
}
|
||||||
|
|
||||||
|
function change(id, isEnabled) {
|
||||||
|
return request('chatbot', { ops: isEnabled ? 'enable' : 'disable', id: id })
|
||||||
|
}
|
||||||
|
|
||||||
|
function showCreate() {
|
||||||
|
location.href = '/apps/chatbot/edit.html';
|
||||||
|
}
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
query(1, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
init();
|
||||||
|
})
|
||||||
|
</script>
|
@ -317,6 +317,15 @@
|
|||||||
</dd>
|
</dd>
|
||||||
</#if>
|
</#if>
|
||||||
</#if>
|
</#if>
|
||||||
|
<#if models?? && models["sales"]?? && models["sales"] == true>
|
||||||
|
<#if user?? &&( user.roleAuthMap["A11"]?? || user.usertype == "0") >
|
||||||
|
<dd class="ukefu-left-menu" data-tooltip="机器人">
|
||||||
|
<a href="javascript:void(0)" data-title="机器人"" data-href="/apps/chatbot/index.html" class="iframe_btn" data-id="maincontent" data-type="tabChange">
|
||||||
|
<i class="kfont" style="position: relative;"></i>
|
||||||
|
</a>
|
||||||
|
</dd>
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
<#if models?? && models["callcenter"]?? && models["callcenter"] == true>
|
<#if models?? && models["callcenter"]?? && models["callcenter"] == true>
|
||||||
<#if user?? && (user.roleAuthMap["A10"]?? || user.usertype == "0") >
|
<#if user?? && (user.roleAuthMap["A10"]?? || user.usertype == "0") >
|
||||||
<dd class="ukefu-left-menu" data-tooltip="语音渠道">
|
<dd class="ukefu-left-menu" data-tooltip="语音渠道">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user