Add OpenAI
Add OpenAI blade fixed openai route 优化 openai wip wip wip wip fixed description logo fixed name and description wip wip wip wip wip code format fixed name and description
This commit is contained in:
parent
575469ca3d
commit
ff6c2211a0
|
|
@ -1,6 +1,7 @@
|
|||
*
|
||||
!FlatShipping
|
||||
!LatestProducts
|
||||
!Openai
|
||||
!Paypal
|
||||
!Social
|
||||
!Stripe
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
/**
|
||||
* Bootstrap.php
|
||||
*
|
||||
* @copyright 2023 beikeshop.com - All Rights Reserved
|
||||
* @link https://beikeshop.com
|
||||
* @author Edward Yang <yangjin@guangda.work>
|
||||
* @created 2023-02-27 13:57:38
|
||||
* @modified 2023-02-27 13:57:38
|
||||
*/
|
||||
|
||||
namespace Plugin\Openai;
|
||||
|
||||
class Bootstrap
|
||||
{
|
||||
public function boot()
|
||||
{
|
||||
add_hook_filter('admin.sidebar.home.prefix', function ($data) {
|
||||
$data[] = 'openai';
|
||||
|
||||
return $data;
|
||||
});
|
||||
|
||||
add_hook_filter('admin.sidebar.home_routes', function ($data) {
|
||||
$data[] = [
|
||||
'route' => 'openai',
|
||||
'title' => 'ChatGPT',
|
||||
];
|
||||
|
||||
return $data;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
/**
|
||||
* OpenaiController.php
|
||||
*
|
||||
* @copyright 2023 beikeshop.com - All Rights Reserved
|
||||
* @link https://beikeshop.com
|
||||
* @author Edward Yang <yangjin@guangda.work>
|
||||
* @created 2023-02-27 16:13:08
|
||||
* @modified 2023-02-27 16:13:08
|
||||
*/
|
||||
|
||||
namespace Plugin\Openai\Controllers;
|
||||
|
||||
use Beike\Admin\Http\Controllers\Controller;
|
||||
|
||||
class OpenaiController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$plugin = app('plugin')->getPlugin('openai');
|
||||
$data = [
|
||||
'name' => $plugin->getLocaleName(),
|
||||
'description' => $plugin->getLocaleDescription(),
|
||||
];
|
||||
|
||||
return view('Openai::admin.openai', $data);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
/**
|
||||
* setting.php
|
||||
*
|
||||
* @copyright 2022 beikeshop.com - All Rights Reserved
|
||||
* @link https://beikeshop.com
|
||||
* @author Edward Yang <yangjin@guangda.work>
|
||||
* @created 2022-08-11 15:26:18
|
||||
* @modified 2022-08-11 15:26:18
|
||||
*/
|
||||
|
||||
return [
|
||||
// Text
|
||||
'title' => 'OpenAI intelligent chat assistant',
|
||||
'sub_title' => 'Based on OpenAI GPT3.0 integrated development If you have any questions, please consult qq group 639108380',
|
||||
'no_question' => 'Please enter the search content in the box below',
|
||||
'enter_question' => 'Please enter a question',
|
||||
'loading' => 'loading...',
|
||||
'no_more' => 'no more',
|
||||
'qa_q' => 'ask',
|
||||
'qa_a' => 'answer',
|
||||
'number_free' => 'The remaining free times of the day',
|
||||
];
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
/**
|
||||
* setting.php
|
||||
*
|
||||
* @copyright 2022 beikeshop.com - All Rights Reserved
|
||||
* @link https://beikeshop.com
|
||||
* @author Edward Yang <yangjin@guangda.work>
|
||||
* @created 2022-08-11 15:26:18
|
||||
* @modified 2022-08-11 15:26:18
|
||||
*/
|
||||
|
||||
return [
|
||||
// Text
|
||||
'title' => 'OpenAI 智能聊天助手',
|
||||
'sub_title' => '基于OpenAI GPT3.0 集成开发 如有疑问详询qq群639108380',
|
||||
'no_question' => '请在下面输入框搜索内容',
|
||||
'enter_question' => '请输入问题',
|
||||
'loading' => '加载中...',
|
||||
'no_more' => '没有更多了',
|
||||
'qa_q' => '问',
|
||||
'qa_a' => '答',
|
||||
'number_free' => '当日剩余免费次数',
|
||||
];
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
/**
|
||||
* setting.php
|
||||
*
|
||||
* @copyright 2022 beikeshop.com - All Rights Reserved
|
||||
* @link https://beikeshop.com
|
||||
* @author Edward Yang <yangjin@guangda.work>
|
||||
* @created 2022-08-11 15:26:18
|
||||
* @modified 2022-08-11 15:26:18
|
||||
*/
|
||||
|
||||
return [
|
||||
// Text
|
||||
'title' => 'OpenAI 智能聊天助手',
|
||||
'sub_title' => '基於OpenAI GPT3.0 集成開發 如有疑問詳詢qq群639108380',
|
||||
'no_question' => '請在下面輸入框搜索內容',
|
||||
'enter_question' => '請輸入問題',
|
||||
'loading' => '加載中...',
|
||||
'no_more' => '没有更多了',
|
||||
'qa_q' => '問',
|
||||
'qa_a' => '答',
|
||||
'number_free' => '當日剩餘免費次數',
|
||||
];
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
/**
|
||||
* admin.php
|
||||
*
|
||||
* @copyright 2022 beikeshop.com - All Rights Reserved
|
||||
* @link https://beikeshop.com
|
||||
* @author Edward Yang <yangjin@guangda.work>
|
||||
* @created 2022-08-04 16:17:53
|
||||
* @modified 2022-08-04 16:17:53
|
||||
*/
|
||||
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Plugin\Openai\Controllers\OpenaiController;
|
||||
|
||||
Route::get('/openai', [OpenaiController::class, 'index'])->name('openai');
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
|
|
@ -0,0 +1,185 @@
|
|||
@extends('admin::layouts.master')
|
||||
|
||||
@section('title', $name)
|
||||
|
||||
@section('content')
|
||||
<div class="row">
|
||||
<div class="col-md-7 col-12 answer-wrap">
|
||||
<div class="border p-3 bg-white" id="answer"><div class="not-answer"><i class="bi bi-activity"></i> {{ __('Openai::common.no_question') }}</div></div>
|
||||
|
||||
<div class="input-group mb-3 mt-4">
|
||||
<input type="text" id="ai-input" class="form-control rounded-0 form-control-lg" placeholder="{{ __('Openai::common.enter_question') }}" aria-label="{{ __('Openai::common.enter_question') }}" aria-describedby="button-addon2">
|
||||
<button class="btn btn-primary px-4 rounded-0" type="button" id="ai-submit"><i class="bi bi-send-fill"></i> {{ __('common.confirm') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-5 col-12">
|
||||
<div class="mb-2"><i class="bi bi-megaphone text-secondary fs-3"></i> </div>
|
||||
<div class="number-free mb-3 fs-5">{{ __('Openai::common.number_free') }}: <span>{{ __('Openai::common.loading') }}</span></div>
|
||||
<div class="text-secondary">{{ $description }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
let last_page = 0;
|
||||
let current_page = 1;
|
||||
|
||||
$('#answer').scroll(function() {
|
||||
if ($(this).scrollTop() == 0) {
|
||||
if (current_page < last_page) {
|
||||
if (!$('.text-loading').length) {
|
||||
$('#answer').prepend('<div class="text-center py-3 text-secondary text-loading"><i class="bi bi-activity"></i> {{ __('Openai::common.loading') }}</div>');
|
||||
}
|
||||
|
||||
clearTimeout(timer);
|
||||
var timer = setTimeout(function() {
|
||||
loadHistories(current_page + 1);
|
||||
}, 300);
|
||||
}
|
||||
|
||||
if (current_page == last_page) {
|
||||
if (!$('.text-loading').length) {
|
||||
$('#answer').prepend('<div class="text-center py-3 text-secondary text-loading"><i class="bi bi-activity"></i> {{ __('Openai::common.no_more') }}</div>');
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$('#answer').height($(window).height() - 260);
|
||||
$(document).ready(function() {
|
||||
loadQuantities();
|
||||
loadHistories();
|
||||
|
||||
$('#ai-input').keydown(function(e) {
|
||||
if (e.keyCode == 13) {
|
||||
$('#ai-submit').click();
|
||||
}
|
||||
})
|
||||
|
||||
$('#ai-submit').click(function() {
|
||||
var question = $('#ai-input').val();
|
||||
if (!question) {
|
||||
return;
|
||||
}
|
||||
|
||||
const $btn = $(this);
|
||||
const btnHtml = $(this).html();
|
||||
const loadHtml = '<span class="spinner-border spinner-border-sm"></span>';
|
||||
|
||||
let html = '';
|
||||
|
||||
$.ajax({
|
||||
url: `${config.api_url}/api/openai/completions`,
|
||||
type: 'POST',
|
||||
headers: {
|
||||
'token': '{{ system_setting('base.developer_token') ?? '' }}'
|
||||
},
|
||||
data: {
|
||||
prompt: question,
|
||||
domain: config.app_url,
|
||||
},
|
||||
beforeSend: function() { $btn.html(loadHtml).prop('disabled', true) },
|
||||
complete: function() { $btn.html(btnHtml).prop('disabled', false) },
|
||||
success: function(data) {
|
||||
if ($('.not-answer').length) {
|
||||
$('.not-answer').remove();
|
||||
}
|
||||
|
||||
if (data.error) {
|
||||
layer.msg(data.error);
|
||||
return;
|
||||
}
|
||||
|
||||
$('.number-free span').text(data.available)
|
||||
|
||||
let answer = data.response.choices[0].text.trim();
|
||||
html += '<div class="answer-list">',
|
||||
html += '<div class="d-flex mb-2"><div class="text-secondary">{{ __('Openai::common.qa_q') }}:</div><div class="w-100">' + question + '</div></div>',
|
||||
html += '<div class="d-flex"><div class="text-secondary">{{ __('Openai::common.qa_a') }}:</div><div class="w-100">' + answer + '</div></div>'
|
||||
html += '</div>'
|
||||
|
||||
$('#ai-input').val('');
|
||||
$('#answer').append(html);
|
||||
$('#answer').scrollTop($('#answer')[0].scrollHeight);
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
function loadQuantities() {
|
||||
$.ajax({
|
||||
url: `${config.api_url}/api/openai/quantities?domain=${config.app_url}`,
|
||||
headers: {
|
||||
'token': '{{ system_setting('base.developer_token') ?? '' }}'
|
||||
},
|
||||
success: function(data) {
|
||||
$('.number-free span').text(data.available)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function loadHistories(page = 1) {
|
||||
$.ajax({
|
||||
url: `${config.api_url}/api/openai/histories?domain=${config.app_url}&page=${page}`,
|
||||
headers: {
|
||||
'token': '{{ system_setting('base.developer_token') ?? '' }}'
|
||||
},
|
||||
success: function(data) {
|
||||
$('.text-loading').remove();
|
||||
last_page = data.last_page;
|
||||
current_page = data.current_page;
|
||||
|
||||
if (data.data.length) {
|
||||
$('.not-answer').remove();
|
||||
|
||||
let html = '';
|
||||
data.data.forEach(function(item, index) {
|
||||
html += '<div class="answer-list '+ (!index ? 'first' : '') +'">',
|
||||
html += '<div class="d-flex mb-2"><div class="text-secondary">{{ __('Openai::common.qa_q') }}:</div><div class="w-100">' + item.question + '</div></div>',
|
||||
html += '<div class="d-flex"><div class="text-secondary">{{ __('Openai::common.qa_a') }}:</div><div class="w-100">' + item.answer + '</div></div>'
|
||||
html += '</div>'
|
||||
})
|
||||
|
||||
$('#answer').prepend(html);
|
||||
if (page == 1) {
|
||||
$('#answer').scrollTop($('#answer')[0].scrollHeight);
|
||||
} else {
|
||||
$('#answer').scrollTop($('#answer .answer-list.first:eq(1)').offset().top - 100 - $('#answer').offset().top);
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
body {
|
||||
background-color: #f4f4f4;
|
||||
}
|
||||
|
||||
#answer {
|
||||
overflow-y: auto;
|
||||
border-radius: 0.25rem;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.not-answer {
|
||||
text-align: center;
|
||||
padding: 100px 0;
|
||||
font-size: 20px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.answer-wrap {
|
||||
max-width: 740px;
|
||||
}
|
||||
|
||||
.answer-list {
|
||||
padding-bottom: 20px;
|
||||
margin-bottom: 20px;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
.answer-list:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
</style>
|
||||
@endsection
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"code": "openai",
|
||||
"name": {
|
||||
"zh_cn": "ChatGPT(OpenAI)智能聊天助手",
|
||||
"en": "Integration with OpenAI"
|
||||
},
|
||||
"description": {
|
||||
"zh_cn": "ChatGPT(OpenAI)智能聊天助手, 基于OpenAI GPT3.0 集成开发, 如有疑问详询QQ群 639108380",
|
||||
"en": "Integration with OpenAI"
|
||||
},
|
||||
"type": "feature",
|
||||
"version": "v1.0.0",
|
||||
"icon": "/image/logo.png",
|
||||
"author": {
|
||||
"name": "成都光大网络科技有限公司",
|
||||
"email": "yangjin@guangda.work"
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue